Cách tốt nhất để tạo một bản đồ trống trong Java


117

Tôi cần tạo một bản đồ trống.

if (fileParameters == null)
    fileParameters = (HashMap<String, String>) Collections.EMPTY_MAP;

Vấn đề là đoạn mã trên tạo ra cảnh báo này: Nhập an toàn: Bỏ chọn truyền từ Bản đồ sang HashMap

Cách tốt nhất để tạo bản đồ trống này là gì?


Kiểu khai báo của bạn cho fileParameters là gì?
jjnguy

Bạn cũng có thể nhận được ClassCastException.
Tom Hawtin - tắc bóng vào

1
fileParameters phải là Bản đồ chứ không phải Bản đồ HashMap.
Steve Kuo

Câu trả lời:


241

1) Nếu Bản đồ có thể là bất biến:

Collections.emptyMap()

// or, in some cases:
Collections.<String, String>emptyMap()

Đôi khi bạn sẽ phải sử dụng cái sau khi trình biên dịch không thể tự động tìm ra loại Bản đồ nào cần thiết (đây được gọi là kiểu suy luận ). Ví dụ, hãy xem xét một phương thức được khai báo như thế này:

public void foobar(Map<String, String> map){ ... }

Khi chuyển trực tiếp Bản đồ trống đến nó, bạn phải rõ ràng về loại:

foobar(Collections.emptyMap());                 // doesn't compile
foobar(Collections.<String, String>emptyMap()); // works fine

2) Nếu bạn cần có thể sửa đổi Bản đồ, thì ví dụ:

new HashMap<String, String>()

(như tehblanx đã chỉ ra )


Phụ lục : Nếu dự án của bạn sử dụng Ổi , bạn có các lựa chọn thay thế sau:

1) Bản đồ bất biến:

ImmutableMap.of()
// or:
ImmutableMap.<String, String>of()

Được cấp, không có lợi ích lớn ở đây so với Collections.emptyMap(). Từ Javadoc :

Bản đồ này hoạt động và thực hiện tương đối Collections.emptyMap()và được ưu tiên chủ yếu vì tính nhất quán và khả năng bảo trì mã của bạn.

2) Bản đồ mà bạn có thể sửa đổi:

Maps.newHashMap()
// or:
Maps.<String, String>newHashMap()

Mapschứa các phương pháp nhà máy tương tự để khởi tạo các loại bản đồ khác, chẳng hạn như TreeMaphoặc LinkedHashMap.


Cập nhật (2018) : Trên Java 9 hoặc mới hơn, mã ngắn nhất để tạo một bản đồ trống bất biến là:

Map.of()

... sử dụng các phương pháp nhà máy tiện lợi mới từ JEP 269 . 😎


Trong hầu hết các trường hợp, kiểu suy luận hoạt động (tức là. Map = Collections.emptyMap () hoạt động)
Sébastien RoccaSerra

Vâng đúng. Tôi đã chỉnh sửa câu trả lời để toàn diện hơn một chút.
Jonik

16

Vấn đề là bản đồ này chỉ có thể được áp dụng cho một đối tượng Bản đồ không phải là một HashMap
JorgeO

7
Bạn nên (nói chung) tránh khai báo các đối tượng thuộc các kiểu cụ thể của chúng và thay vào đó hãy sử dụng giao diện (hoặc cha mẹ trừu tượng). Cố gắng tránh "HashMap <String, String> foo;" và sử dụng "Map <String, String> foo;" thay vào đó
TofuBeer


10

Nếu bạn cần một phiên bản của HashMap, cách tốt nhất là:

fileParameters = new HashMap<String,String>();

Vì Bản đồ là một giao diện, bạn cần chọn một số lớp khởi tạo nó nếu bạn muốn tạo một thể hiện trống. HashMap có vẻ tốt như bất kỳ cái nào khác - vì vậy chỉ cần sử dụng nó.


7

Hoặc Collections.emptyMap()nếu suy luận kiểu không hoạt động trong trường hợp của bạn,
Collections.<String, String>emptyMap()


2

Vì trong nhiều trường hợp, một bản đồ trống được sử dụng cho thiết kế không an toàn, bạn có thể sử dụng nullToEmptyphương pháp tiện ích:

class MapUtils {

  static <K,V> Map<K,V> nullToEmpty(Map<K,V> map) {
    if (map != null) {
      return map;
    } else {
       return Collections.<K,V>emptyMap(); // or guava ImmutableMap.of()
    }
  }

}  

Tương tự cho các bộ:

class SetUtils {

  static <T> Set<T> nullToEmpty(Set<T> set) {
    if (set != null) {
      return set;
    } else {
      return Collections.<T>emptySet();
    }
  }

}

và danh sách:

class ListUtils {

  static <T> List<T> nullToEmpty(List<T> list) {
    if (list != null) {
      return list;
    } else {
      return Collections.<T>emptyList();
    }
  }

}

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.