[英]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 處理來准備一些演示數據,但我在最終解決方案中避免使用它以保持處理更高效(基於我的測試),因為我不知道地圖的大小。
我還修改了您的enum
和class
以啟用它們的使用。
首先,創建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.