簡體   English   中英

Java中的2個HashMap的過濾和合並

[英]Filtering and Merging 2 HashMap's in Java

我有一個 Map 有一個鍵 - ItemType 一個枚舉和一組項目名稱(字符串)
Map<ItemType, Set<String> itemTypesAndNames;
例如。
鍵:ItemType1,值:a1、a2、a3
鍵:ItemType2,值:b1、b2、b3
鍵:ItemType3,值:c1,c2,c 3

第二個 map 是

Map<String, ItemId> itemNamesAndIds;

例如。
鍵:a1,值:1234556-434
鍵:a2,值:4324234-5453
鍵:b1 值:3t5dgsfdfdsf
等等

我想用 ItemType 和一組 itemTypeIds 創建一個新的 map
Map <ItemType, Set<ItemId>>
例如
鍵:ItemType1,值:1234556-434、4324234-545
鍵:ItemType2,值:3t5dgsfdfdsf
等等

public class ItemId {
private final String id;
public static ItemId of(String id) { 
return new ItemId (id)}
 }
}

public enum ItemType {
 ITEM_TYPE_1("ItemType1");
 ITEM_TYPE_2("ItemType2");
}

Set<String>中的值應重新映射到Set<ItemId> (可能只保留itemNamesAndIds映射中可用的ids ):

Map<ItemType, Set<ItemId>> remapped = itemTypesAndNames.entrySet()
        .stream()
        .collect(Collectors.toMap(
            Map.Entry::getKey,
            e -> e.getValue().stream()
                .filter(itemNamesAndIds::containsKey)
                .map(itemNamesAndIds::get)
                .collect(Collectors.toSet())
        ));

更新
如果必須合並具有相同結構Map<Key, Set<Value>>的兩個映射,則可以使用toMap收集器和合並 function 來實現:

Map<Key, Set<Value>> map1 = ...; // init map1
Map<Key, Set<Value>> map2 = ...; // init map2

Map<Key, Set<Value>> merged = Stream.concat(
        map1.entrySet().stream(), map2.entrySet().stream()
    )
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (v1, v2) -> { v1.addAll(v2); return v1; } // assuming that the sets are not immutable
    ));

這是一種方法。 雖然我使用了一些 stream 處理來准備一些演示數據,但我在最終解決方案中避免使用它以保持處理更高效(基於我的測試),因為我不知道地圖的大小。

我還修改了您的enumclass以啟用它們的使用。

首先,創建itemTypesAndNames map。

Map<ItemType, Set<String>> itemTypesAndNames = Map.of(
        ItemType.ITEM_TYPE_1,
        Set.of("a1", "a2", "a3"),
        ItemType.ITEM_TYPE_2,
        Set.of("b1", "b2", "b3"),
        ItemType.ITEM_TYPE_3,
        Set.of("c1", "c2", "c3"));

itemTypesAndNames.entrySet().forEach(System.out::println);

印刷

ITEM_TYPE_2=[b2, b1, b3]
ITEM_TYPE_3=[c1, c3, c2]
ITEM_TYPE_1=[a3, a2, a1]

現在創建itemNamesAndIds map

Supplier<ItemId> itemId = () -> new ItemId(Integer
        .toString((int)(Math.random() * 89999) + 10000));

Map<String, ItemId> itemNamesAndIds = itemTypesAndNames
        .values().stream().flatMap(Set::stream)
        .collect(Collectors.toMap(Function.identity(),
                k -> itemId.get()));

itemNamesAndIds.entrySet().forEach(System.out::println);

印刷

a1=83334
c3=99557
b2=18211
a2=91979
b3=41222
a3=78181
c1=38114
c2=56413
b1=68386

創建一個目標 map 並簡單地遍歷類型和名稱,如果它存在於itemNamesAndIds map 中,則為該名稱創建一個條目。 如果目標set不存在, computeIfAbsent創建它。

Map<ItemType, Set<ItemId>> typesAndIds = new HashMap<>();

for (Map.Entry<ItemType, Set<String>> e : itemTypesAndNames
        .entrySet()) {
    for (String name : e.getValue()) {
        if (itemNamesAndIds.containsKey(name)) {
            typesAndIds
                    .computeIfAbsent(e.getKey(),
                            v -> new HashSet<>())
                    .add(itemNamesAndIds.get(name));
        }
    }
}

typesAndIds.entrySet().forEach(System.out::println);

打印類似的東西

ITEM_TYPE_3=[99557, 38114, 56413]
ITEM_TYPE_1=[83334, 78181, 91979]
ITEM_TYPE_2=[18211, 68386, 41222]

數據對象。

class ItemId {
    private final String id;
    
    public ItemId(String id) {
        this.id = id;
    }
    
    public static ItemId of(String id) {
        return new ItemId(id);
    }
    
    public String getId() {
        return id;
    }
    
    public String toString() {
        return id;
    }
}

enum ItemType {
    ITEM_TYPE_1("ItemType1"),
    ITEM_TYPE_2("ItemType2"),
    ITEM_TYPE_3("ItemType3");

    private String itemType;

    private ItemType(String t) {
        this.itemType = t;
    }
    
    public String getType() {
        return itemType;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM