2013-04-19 37 views
17

Tại một thời điểm trong mã của tôi, tôi đã tạo một Set<Map.Entry<K, V>> từ bản đồ. Bây giờ tôi muốn tạo lại cùng một biểu mẫu bản đồ, vì vậy tôi muốn chuyển đổi HashSet<Map.Entry<K, V>> trở lại thành HashMap<K, V>. Liệu Java có một cuộc gọi bản địa để làm điều này, hay tôi phải lặp qua các yếu tố thiết lập và xây dựng bản đồ lên bằng tay?Chuyển đổi bộ <Map.Entry <K, V>> thành HashMap <K, V>

+0

Làm thế nào mà bạn đã tạo 'Set' từ 'Map', sử dụng khóa hoặc giá trị hoặc tùy chỉnh logic? bên cạnh đó không có phương thức 'native' cho' HashSet' thành 'HashMap'. Bạn cần phải lặp lại và sử dụng một số logic như trong khi đưa vào 'HashMap' cách bạn chọn khóa và giá trị. – harsh

+0

@Paul nhờ câu hỏi hiện tại có ý nghĩa rõ ràng – harsh

+1

Tôi không nghĩ rằng 'Map.Entry' có nghĩa là được sử dụng theo cách này. Việc thực hiện được sử dụng bởi 'HashMap' ghi đè lên' hashCode' và 'equals' chẳng hạn? –

Trả lời

17

Không có API sẵn có trong java để chuyển đổi trực tiếp giữa HashSetHashMap, bạn cần phải lặp qua thiết lập và sử dụng Entry điền vào bản đồ.

một cách tiếp cận:

Map<Integer, String> map = new HashMap<Integer, String>(); 
    //fill in map 
    Set<Entry<Integer, String>> set = map.entrySet(); 

    Map<Integer, String> mapFromSet = new HashMap<Integer, String>(); 
    for(Entry<Integer, String> entry : set) 
    { 
     mapFromSet.put(entry.getKey(), entry.getValue()); 
    } 

Mặc dù là mục đích gì ở đây, nếu bạn làm bất kỳ thay đổi trong Set rằng cũng sẽ phản ánh trong Map như thiết lập được trả về bởi Map.entrySet là sao lưu bởi Map. Xem javadoc dưới đây:

Đặt < nhập < Integer, String >> java.util.Map.entrySet()

Trả một cái nhìn Set của ánh xạ chứa trong bản đồ này. Bộ này là được bản đồ sao lưu, vì vậy các thay đổi đối với bản đồ được phản ánh trong bộ này và ngược lại. Nếu bản đồ được sửa đổi trong khi lặp lại trên tập hợp là đang tiến hành (ngoại trừ thông qua thao tác xóa của trình lặp, hoặc thông qua thao tác setValue trên một mục bản đồ được trả về bởi trình lặp ), kết quả của phép lặp không xác định. Bộ này hỗ trợ xóa phần tử , loại bỏ ánh xạ tương ứng khỏi bản đồ, qua Iterator.remove, Set.remove, removeAll, retainAll và xóa hoạt động . Nó không hỗ trợ các hoạt động thêm hoặc addAll.

1

Giải pháp Java 8 khá ngắn. Có thể đối phó với các phím trùng lặp.

Map<Integer, String> map = new HashMap<>(); 
    //fill in map 
    Set<Map.Entry<Integer, String>> set = map.entrySet(); 
    Map<Integer, String> mapFromSet = set.stream().collect(Collectors.toMap(Entry::getKey, 
     Entry::getValue, 
     (a,b)->b)); 

Edit: nhờ shmosel người xứng đáng tín dụng nhiều hơn tôi làm cho điều này

+0

No. BiConsumer của bạn không kết hợp Bản đồ. – Joe

+0

Trong đoạn mã trên, phương thức chấp nhận của BiConsumer không bao giờ được gọi. Tôi đã có thể ưa thích sử dụng null nhưng phương pháp thu thập ngớ ngẩn ném một NPE trong trường hợp đó. – mikeyreilly

+1

@mikeyreilly, [tài liệu] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect-java.util.function.Supplier-java.util .function.BiConsumer-java.util.function.BiConsumer-) không nói rõ ràng rằng bộ kết hợp không bao giờ được gọi là luồng tuần tự. Vì vậy, bạn chỉ vi phạm hợp đồng của phương pháp. –

0

Trong Java 8 với bộ kết hợp đúng

Map<Integer, String> map = new HashMap<>(); 
//fill in map 
Set<Map.Entry<Integer, String>> set = map.entrySet(); 

Map<Integer, String> mapFromSet =set.stream().collect(HashMap::new,(t, u) -> t.put(u.getKey(), u.getValue()), 
(Map mapToReturn, Map otherMap) -> 
    { 
     otherMap.entrySet().forEach((Map.Entry entry) -> { 
      mapToReturn.put(entry.getKey(),entry.getValue()); 
     }); 
     return mapToReturn;});); 
26

đơn giản-8 Java giải pháp liên quan đến Collectors.toMap:

Map<Integer, String> mapFromSet = set.stream() 
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); 

An IllegalStateException sẽ bị ném nếu d phím gặp phải được gặp phải.

+0

NPE aboug gì nếu giá trị nào là null? –

0

Tính đến Java 9, chúng tôi có Map.ofEntries. Họ chỉ lấy các mục như là một mảng mặc dù, vì vậy bạn cần phải chuyển đổi chúng đầu tiên với toArray() và ném ra các thông tin kiểu.

@SuppressWarnings("unchecked") 
(Map.Entry<K, V>[] array = entrySet.toArray((Map.Entry<K, V>[])new Map.Entry<?, ?>[entrySet.size()]); 
Map<K, V> map = Map.ofEntries(array); 

Apache Commons có các phương pháp tương tự.Commons Lang ArrayUtils.toMap:

Map<Object, Object> map = ArrayUtils.toMap(entrySet.toArray()); 

// to recover the type... 
@SuppressWarnings("unchecked") 
Map<K, V> typedMap = (Map<K, V>)(Map<?, ?>)map; 

Commons Bộ sưu tập MapUtils.putAll:

Map<K, V> map = MapUtils.putAll(new HashMap<K, V>(), entrySet.toArray()); 
Các vấn đề liên quan