thêm nhiều mục vào HashMap cùng một lúc trong một câu lệnh


138

Tôi cần khởi tạo một HashMap không đổi và muốn thực hiện nó trong một câu lệnh. Tránh sth như thế này:

  hashMap.put("One", new Integer(1)); // adding value into HashMap
  hashMap.put("Two", new Integer(2));      
  hashMap.put("Three", new Integer(3));

tương tự như điều này trong mục tiêu C:

[NSDictionary dictionaryWithObjectsAndKeys:
@"w",[NSNumber numberWithInt:1],
@"K",[NSNumber numberWithInt:2],
@"e",[NSNumber numberWithInt:4],
@"z",[NSNumber numberWithInt:5],
@"l",[NSNumber numberWithInt:6],
nil] 

Tôi đã không tìm thấy bất kỳ ví dụ cho thấy làm thế nào để làm điều này đã xem xét rất nhiều.

Câu trả lời:


258

Bạn có thể làm được việc này:

Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
     put("One", 1);
     put("Two", 2);
     put("Three", 3);
}};

11
@ user387184 Vâng, họ gọi nó là "trình khởi tạo cú đúp". Xem chủ đề này: stackoverflow.com/questions/924285/
Mạnh

2
Tôi chỉ cần đặt nó vào mã của mình và tôi nhận được thông báo / thông báo này trong dòng: "Lớp tuần tự hóa không khai báo trường serialVersionUID tĩnh cuối cùng của loại dài". Tôi có thể bỏ qua điều đó? Điều đó có nghĩa là gì? Cảm ơn
dùng387184

31
Bạn không nên sử dụng phương pháp này. Nó tạo ra một lớp mới cho mỗi thời gian mà bạn sử dụng nó, trong đó có nhiều hoạt động tồi tệ hơn chỉ rõ ràng tạo ra một bản đồ. Xem stackoverflow.com/questions/924285/ từ
Timo Türschmann

7
Lý do tôi đánh giá thấp điều này là vì nó không giải thích rằng điều này tạo ra một lớp mới cho mỗi lần bạn sử dụng nó. Tôi nghĩ rằng mọi người nên nhận thức được sự đánh đổi khi làm theo cách này.
idungotnosn

6
@ TimoTürschmann Có vẻ như nếu tôi cần khởi tạo tĩnh một bản đồ như thế này, thì nó cũng sẽ tĩnh, loại bỏ mỗi khi bạn sử dụng hình phạt hiệu suất - bạn sẽ bị phạt một lần. Tôi không thể thấy bất kỳ lúc nào khác mà người ta muốn loại khởi tạo này mà không có biến tĩnh (ví dụ, có ai từng sử dụng điều này trong một vòng lặp không?). Tôi có thể sai mặc dù, lập trình viên là sáng tạo.
Chris Cirefice

65

Bạn có thể sử dụng Bản đồ bất biến của Google Guava. Điều này hoạt động miễn là bạn không quan tâm đến việc sửa đổi Bản đồ sau này (bạn không thể gọi .put () trên bản đồ sau khi xây dựng nó bằng phương pháp này):

import com.google.common.collect.ImmutableMap;

// For up to five entries, use .of()
Map<String, Integer> littleMap = ImmutableMap.of(
    "One", Integer.valueOf(1),
    "Two", Integer.valueOf(2),
    "Three", Integer.valueOf(3)
);

// For more than five entries, use .builder()
Map<String, Integer> bigMap = ImmutableMap.<String, Integer>builder()
    .put("One", Integer.valueOf(1))
    .put("Two", Integer.valueOf(2))
    .put("Three", Integer.valueOf(3))
    .put("Four", Integer.valueOf(4))
    .put("Five", Integer.valueOf(5))
    .put("Six", Integer.valueOf(6))
    .build();

Xem thêm: http://docs.guava-lologists.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html

Một câu hỏi hơi liên quan: cách giải quyết của ImmutableMap.of () cho HashMap trong Bản đồ?


Quả ổi rất lớn, tôi sẽ không sử dụng nó cho ứng dụng Android của mình trừ khi thực sự cần thiết
ericn

4
Coi chừng ImmutableMapkhông chấp nhận nullkhóa hoặc giá trị.
Vadzim

@ericn ProGuard cho phép bạn loại trừ bất kỳ phần nào của thư viện bạn không sử dụng.
dimo414

55

Kể từ Java 9, có thể sử dụng Map.of(...), như vậy:

Map<String, Integer> immutableMap = Map.of("One", 1, 
                                           "Two", 2, 
                                           "Three", 3);

Bản đồ này là bất biến. Nếu bạn muốn bản đồ có thể thay đổi, bạn phải thêm:

Map<String, Integer> hashMap = new HashMap<>(immutableMap);

Nếu bạn không thể sử dụng Java 9, bạn sẽ bị mắc kẹt khi tự viết một phương thức trợ giúp tương tự hoặc sử dụng thư viện của bên thứ ba (như Guava ) để thêm chức năng đó cho bạn.


Sau khi thêm 10 mục, nó đưa ra lỗi lạ "không thể giải quyết phương thức", đây có phải là lỗi với phương thức này không?
vikramvi

2
@vikramvi có Nếu bạn xem tài liệu Map.of chỉ được thực hiện tối đa 10 mục vì nó khá tốn công
jolivier

8

Java không có bản đồ theo nghĩa đen, vì vậy không có cách nào hay để làm chính xác những gì bạn yêu cầu.

Nếu bạn cần loại cú pháp đó, hãy xem xét một số Groovy, tương thích với Java và cho phép bạn thực hiện:

def map = [name:"Gromit", likes:"cheese", id:1234]

8

Bản đồ cũng đã có các phương thức xuất xưởng được thêm vào trong Java 9. Trong tối đa 10 mục Bản đồ có các hàm tạo quá tải lấy các cặp khóa và giá trị. Ví dụ: chúng tôi có thể xây dựng bản đồ của các thành phố khác nhau và dân số của họ (theo google vào tháng 10 năm 2016) như sau:

Map<String, Integer> cities = Map.of("Brussels", 1_139000, "Cardiff", 341_000);

Trường hợp var-args cho Map khó hơn một chút, bạn cần có cả khóa và giá trị, nhưng trong Java, các phương thức không thể có hai tham số var-args. Vì vậy, trường hợp chung được xử lý bằng cách sử dụng một phương thức var-args của Map.Entry<K, V>các đối tượng và thêm một entry()phương thức tĩnh xây dựng chúng. Ví dụ:

Map<String, Integer> cities = Map.ofEntries(
    entry("Brussels", 1139000), 
    entry("Cardiff", 341000)
);

Các phương thức của bộ sưu tập trong Java 9


Tuyệt vời nếu bạn có thể sử dụng Java 9+. Ngoài ra các phương pháp nhà máy trả về bản đồ bất biến.
Sourabh

6

Đây là một lớp đơn giản sẽ thực hiện những gì bạn muốn

import java.util.HashMap;

public class QuickHash extends HashMap<String,String> {
    public QuickHash(String...KeyValuePairs) {
        super(KeyValuePairs.length/2);
        for(int i=0;i<KeyValuePairs.length;i+=2)
            put(KeyValuePairs[i], KeyValuePairs[i+1]);
    }
}

Và sau đó sử dụng nó

Map<String, String> Foo=QuickHash(
    "a", "1",
    "b", "2"
);

Sản lượng này {a:1, b:2}


4
    boolean x;
    for (x = false, 
        map.put("One", new Integer(1)), 
        map.put("Two", new Integer(2)),      
        map.put("Three", new Integer(3)); x;);

Bỏ qua tuyên bố x(cần thiết để tránh chẩn đoán "tuyên bố không thể truy cập"), về mặt kỹ thuật, đó chỉ là một tuyên bố.


14
Đây là hacky ghê tởm.
Cầu thang Micah

1
@MicahStairs - Nhưng đó chỉ là một tuyên bố.
Hot Licks

2
Đúng, nhưng đây là loại mã mà tôi không bao giờ hy vọng sẽ vấp ngã trong sản xuất.
Cầu thang Micah

@MicahStairs - Tôi đã thấy tồi tệ hơn.
Hot Licks

1
Omg tôi đã tìm kiếm cho ngày hôm nay, làm thế nào mã này hoạt động? Tôi đã thêm nó vào mã để thử nghiệm nhưng tôi không thể tìm ra cách nó hoạt động bên trong ... :)
GOXR3PLUS

1

Bạn có thể thêm chức năng tiện ích này vào một lớp tiện ích:

public static <K, V> Map<K, V> mapOf(Object... keyValues) {
    Map<K, V> map = new HashMap<>();

    for (int index = 0; index < keyValues.length / 2; index++) {
        map.put((K)keyValues[index * 2], (V)keyValues[index * 2 + 1]);
    }

    return map;
}

Map<Integer, String> map1 = YourClass.mapOf(1, "value1", 2, "value2");
Map<String, String> map2 = YourClass.mapOf("key1", "value1", "key2", "value2");

Lưu ý: trong Java 9bạn có thể sử dụng Map.of


-1

Một cách tiếp cận khác có thể là viết hàm đặc biệt để trích xuất tất cả các giá trị phần tử từ một chuỗi bằng biểu thức chính quy:

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Example {
    public static void main (String[] args){
        HashMap<String,Integer> hashMapStringInteger = createHashMapStringIntegerInOneStat("'one' => '1', 'two' => '2' , 'three'=>'3'  ");

        System.out.println(hashMapStringInteger); // {one=1, two=2, three=3}
    }

    private static HashMap<String, Integer> createHashMapStringIntegerInOneStat(String str) {
        HashMap<String, Integer> returnVar = new HashMap<String, Integer>();

        String currentStr = str;
        Pattern pattern1 = Pattern.compile("^\\s*'([^']*)'\\s*=\\s*>\\s*'([^']*)'\\s*,?\\s*(.*)$");

        // Parse all elements in the given string.
        boolean thereIsMore = true;
        while (thereIsMore){
            Matcher matcher = pattern1.matcher(currentStr);
            if (matcher.find()) {
                returnVar.put(matcher.group(1),Integer.valueOf(matcher.group(2)));
                currentStr = matcher.group(3);
            }
            else{
                thereIsMore = false;
            }
        }

        // Validate that all elements in the given string were parsed properly
        if (currentStr.length() > 0){
            System.out.println("WARNING: Problematic string format. given String: " + str);
        }

        return returnVar;
    }
}
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.