Mảng liên kết Java


214

Làm cách nào tôi có thể tạo và tìm nạp các mảng kết hợp trong Java như tôi có thể trong PHP?

Ví dụ:

$arr[0]['name'] = 'demo';
$arr[0]['fname'] = 'fdemo';
$arr[1]['name'] = 'test';
$arr[1]['fname'] = 'fname';

Câu trả lời:


356

Java không hỗ trợ các mảng kết hợp, tuy nhiên điều này có thể dễ dàng đạt được bằng cách sử dụng a Map. Ví dụ,

Map<String, String> map = new HashMap<String, String>();
map.put("name", "demo");
map.put("fname", "fdemo");
// etc

map.get("name"); // returns "demo"

Thậm chí chính xác hơn với ví dụ của bạn (vì bạn có thể thay thế Chuỗi bằng bất kỳ đối tượng nào đáp ứng nhu cầu của bạn) sẽ được khai báo:

List<Map<String, String>> data = new ArrayList<>();
data.add(0, map);
data.get(0).get("name"); 

Xem tài liệu chính thức để biết thêm thông tin


2
Điều này sẽ ném NullPointerExceptionnếu bản đồ bên ngoài không chứa bản đồ cho mục nhập 0. Không phải PHP dễ dãi hơn với $ Array [0] ['name'] (Tôi hoàn toàn không biết ngôn ngữ này)?
Tomasz Nurkiewicz

9
PHP sẽ không thích nếu bạn cố truy cập khóa không tồn tại, không :)
Svish

2
@edem, một số thực hiện là cần thiết. Tuy nhiên, ngày nay , tôi thích ArrayListtrong hầu hết các trường hợp do sự khác biệt về hiệu suất (không mong đợi?). Nhưng đó là một cuộc thảo luận khác.
Johan Sjöberg

3
Không bao giờ quên khởi tạo kích thước băm chính xác và đặt hệ số tải là 1: HashMap <String, String> (dung lượng, 1). Nếu không, bạn có thể thực hiện một chi phí rất lớn và các đối tượng của bạn cần nhiều RAM. +1 cho ArrayList, nhưng tại sao không chỉnh sửa câu trả lời?
Marcus

1
@Marcus " Không bao giờ quên khởi tạo kích thước băm chính xác và đặt hệ số tải là 1 " - bạn nhận được lời khuyên đó ở đâu? Bạn gần như không bao giờ nên chỉ định hệ số tải của a HashMap, và chắc chắn không phải là không cố ý điểm chuẩn hành vi và tìm hệ số tải tốt hơn cho trường hợp sử dụng của bạn. Lý do duy nhất để xác định kích thước ban đầu là nếu bạn biết trước rằng bản đồ sẽ rất rộng. HashMapkhông lãng phí (nhiều) bộ nhớ nếu trống, nhưng nếu bạn có ý định tạo một bản đồ lớn, bạn có thể lưu một số thay đổi kích thước mảng bằng cách chỉ định kích thước của nó ở phía trước.
dimo414

47

Java không có mảng kết hợp như PHP.

Có nhiều giải pháp khác nhau cho những gì bạn đang làm, chẳng hạn như sử dụng Bản đồ, nhưng nó phụ thuộc vào cách bạn muốn tra cứu thông tin. Bạn có thể dễ dàng viết một lớp chứa tất cả thông tin của bạn và lưu trữ các thể hiện của chúng trong một ArrayList.

public class Foo{
    public String name, fname;

    public Foo(String name, String fname){
        this.name = name;
        this.fname = fname;
    }
}

Và sau đó...

List<Foo> foos = new ArrayList<Foo>();
foos.add(new Foo("demo","fdemo"));
foos.add(new Foo("test","fname"));

Vì vậy, bạn có thể truy cập chúng như ...

foos.get(0).name;
=> "demo"

20

Bạn có thể thực hiện điều này thông qua Bản đồ. Cái gì đó như

Map<String, String>[] arr = new HashMap<String, String>[2]();
arr[0].put("name", "demo");

Nhưng khi bạn bắt đầu sử dụng Java, tôi chắc chắn bạn sẽ thấy rằng nếu bạn tạo một lớp / mô hình đại diện cho dữ liệu của bạn sẽ là các tùy chọn tốt nhất của bạn. tôi sẽ làm

class Person{
String name;
String fname;
}
List<Person> people = new ArrayList<Person>();
Person p = new Person();
p.name = "demo";
p.fname = "fdemo";
people.add(p);

Tôi nghĩ rằng tôi thích phương pháp này tốt hơn cảm ơn. Đến từ php, nơi mọi thứ đơn giản đến mức khó xử khi sử dụng java, nhưng giải pháp tuyệt vời. Cảm ơn.
băng giá

Tại sao nên sử dụng List thay vì ArrayList? một người mới java ở đây.
Sobiaholic 18/03/2015

'Danh sách' là một lớp trừu tượng và 'ArrayList' là một trong những triển khai của lớp đó, có các loại danh sách khác có nguồn gốc từ cùng một lớp trừu tượng. Vì vậy, vì điều này, ArrayList cũng là một Danh sách. Bạn không thể tạo một thể hiện của một lớp trừu tượng, chỉ cần sử dụng nó như kiểu ở đây, bạn cần sử dụng triển khai cho các thể hiện của mình. Vì vậy, Danh sách là loại và ArrayList là ví dụ ở đây.
veta

12

Không có thứ gọi là mảng kết hợp trong Java. Họ hàng gần nhất của nó là mộtMap , được gõ mạnh, tuy nhiên có cú pháp / API kém thanh lịch.

Đây là cách gần nhất bạn có thể nhận được dựa trên ví dụ của bạn:

Map<Integer, Map<String, String>> arr = 
    org.apache.commons.collections.map.LazyMap.decorate(
         new HashMap(), new InstantiateFactory(HashMap.class));

//$arr[0]['name'] = 'demo';
arr.get(0).put("name", "demo");

System.out.println(arr.get(0).get("name"));
System.out.println(arr.get(1).get("name"));    //yields null

1
Những gì LazyMap.decorateInstantiateFactoryvà công cụ cho?
Svish

+1 Tất cả các câu trả lời khác dường như cho rằng một trong các "khóa" là một số nguyên. Điều gì xảy ra nếu mảng liên kết dựa trên hai khóa không nguyên (một tuple mà chúng ta sẽ nói trong python)? Tôi tin rằng bạn sẽ cần sử dụng phương pháp này vì việc lập chỉ mục trở nên bất khả thi.
demongolem

10

Nhìn vào giao diện Bản đồ và lớp HashMap cụ thể .

Để tạo Bản đồ:

Map<String, String> assoc = new HashMap<String, String>();

Để thêm cặp khóa-giá trị:

assoc.put("name", "demo");

Để lấy giá trị được liên kết với khóa:

assoc.get("name")

Và chắc chắn, bạn có thể tạo một mảng Bản đồ, vì đó dường như là những gì bạn muốn:

Map<String, String>[] assoc = ...

6

Vâng, tôi cũng đã tìm kiếm mảng Associative và tìm thấy Danh sách bản đồ là giải pháp tốt nhất.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class testHashes {

public static void main(String args[]){
    Map<String,String> myMap1 = new HashMap<String, String>();

    List<Map<String , String>> myMap  = new ArrayList<Map<String,String>>();

    myMap1.put("URL", "Val0");
    myMap1.put("CRC", "Vla1");
    myMap1.put("SIZE", "Vla2");
    myMap1.put("PROGRESS", "Vla2");

    myMap.add(0,myMap1);
    myMap.add(1,myMap1);

    for (Map<String, String> map : myMap) {
        System.out.println(map.get("URL"));
    }

    //System.out.println(myMap);

}


}


5

Java không có mảng kết hợp, thứ gần nhất bạn có thể nhận được là giao diện Bản đồ

Đây là một mẫu từ trang đó.

import java.util.*;

public class Freq {
    public static void main(String[] args) {
        Map<String, Integer> m = new HashMap<String, Integer>();

        // Initialize frequency table from command line
        for (String a : args) {
            Integer freq = m.get(a);
            m.put(a, (freq == null) ? 1 : freq + 1);
        }

        System.out.println(m.size() + " distinct words:");
        System.out.println(m);
    }
}

Nếu chạy với:

java Freq if it is to be it is up to me to delegate

Bạn sẽ nhận được:

8 distinct words:
{to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2}

3

Các mảng kết hợp trong Java như trong PHP:

SlotMap hmap = new SlotHashMap();
String key = "k01";
String value = "123456";
// Add key value
hmap.put( key, value );

// check if key exists key value
if ( hmap.containsKey(key)) {
    //.....        
}

// loop over hmap
Set mapkeys =  hmap.keySet();
for ( Iterator iterator = mapkeys.iterator(); iterator.hasNext();) {
  String key = (String) iterator.next();
  String value = hmap.get(key);
}

Thêm thông tin, xem Class SoftHashMap: https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/util/SoftHashMap.html


Phương thức Map.containsKey () lặp qua tất cả các khóa của Map và phương thức Map.get () cũng trả về giá trị một cách tự nhiên khi tìm thấy khóa. Vì vậy, chỉ Map.get () thực hiện cả hai kỹ thuật đó, chỉ một lần (để thực hiện nhiều hơn), mà không cần viết mã mới này. Ngoài ra Map.get () trả về giá trị được liên kết với khóa đầu tiên được khớp và sau đó dừng tìm kiếm, tốc độ nhanh hơn và hành vi quen thuộc cho mẫu này. Mã trong bài đăng này tiếp tục lặp qua tất cả các khóa ngay cả sau khi khóa tìm kiếm được khớp và trả về khóa khớp cuối cùng (không phải khóa khớp đầu tiên).
Matthew

3

Sử dụng ArrayList <Map <String, String >>

Đây là một mẫu mã:

ArrayList<Map<String, String>> products = new ArrayList<Map<String, String>>();
while (iterator.hasNext()) {
         Map<String, String> product = new HashMap<String, String>();
         Element currentProduct = iterator.next();
         product.put("id",currentProduct.get("id"));
         product.put("name" , currentProduct.get("name") );
         products.add(product );
}
System.out.println("products : " + products);

Đầu ra:

sản phẩm: [{id = 0001, name = prod1}, {id = 0002, name = prod2}]


1

Trong JDK 1.5 (http://tinyurl.com/3m2lxju) thậm chí còn có một lưu ý: "LƯU Ý: Lớp này đã lỗi thời. Việc triển khai mới nên triển khai giao diện Bản đồ, thay vì mở rộng lớp này." Trân trọng, N.


1
Object[][] data = {
{"mykey1", "myval1"},
{"mykey2", "myval2"},
{new Date(), new Integer(1)},
};

Vâng, điều này đòi hỏi phải lặp đi lặp lại để tìm kiếm giá trị theo khóa, nhưng nếu bạn cần tất cả chúng, đây sẽ là lựa chọn tốt nhất.



0

Suy nghĩ nhiều hơn về nó, tôi muốn loại bỏ các bộ dữ liệu như một cách xử lý vấn đề chung hơn. Mặc dù các bộ dữ liệu không có nguồn gốc từ Java, tôi sử dụng Javatuples để cung cấp cho tôi chức năng tương tự tồn tại trong các ngôn ngữ khác. Một ví dụ về cách đối phó với câu hỏi được hỏi là

Map<Pair<Integer, String>, String> arr = new HashMap<Pair<Integer, String>, String>();
Pair p1 = new Pair(0, "name");
arr.put(p1, "demo");

Tôi thích cách tiếp cận này vì nó có thể được mở rộng thành ba lần và các nhóm có thứ tự cao hơn khác với các lớp và phương thức do api cung cấp.


-2

Về nhận xét PHP 'Không, PHP sẽ không thích nó'. Trên thực tế, PHP sẽ tiếp tục hoạt động trừ khi bạn đặt một số mức độ ngoại lệ / lỗi rất hạn chế (đối với PHP), (và thậm chí có thể không xảy ra sau đó).

Điều SILL xảy ra theo mặc định là quyền truy cập vào một biến không tồn tại / nằm ngoài giới hạn của phần tử mảng 'hủy cài đặt' giá trị của bạn mà bạn đang gán. KHÔNG, đó là KHÔNG. PHP có một dòng dõi Perl / C, từ những gì tôi hiểu. Vì vậy, có: các biến không đặt và không tồn tại, các giá trị được đặt nhưng là các giá trị NULL, Boolean Sai, sau đó mọi thứ khác mà các langau chuẩn có. Bạn phải kiểm tra riêng cho những cái đó, HOẶC chọn đánh giá PHẢI được xây dựng theo hàm / cú pháp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.