过滤和合并2个HashMap';Java中的s
我有一个映射,它有一个key-ItemType、一个enum和一组项名称(String)过滤和合并2个HashMap';Java中的s,java,dictionary,hashmap,Java,Dictionary,Hashmap,我有一个映射,它有一个key-ItemType、一个enum和一组项名称(String) Map应将集合中的值重新映射到集合(可能只保留id在itemNamesAndIdsMap中可用): Map remap=itemTypesAndNames.entrySet() .stream() .collect(collector.toMap)( Map.Entry::getKey, e->e.getValue().stream() .filter(ItemNamesAndId::containsKe
Map应将集合
中的值重新映射到集合
(可能只保留id
在itemNamesAndIds
Map中可用):
Map remap=itemTypesAndNames.entrySet()
.stream()
.collect(collector.toMap)(
Map.Entry::getKey,
e->e.getValue().stream()
.filter(ItemNamesAndId::containsKey)
.map(ItemNamesAndId::get)
.collect(收集器.toSet())
));
更新
如果必须合并具有相同结构的两个映射Map
,可以使用带合并功能的toMap
收集器来实现:
map1=…;//初始化映射1
映射map2=…;//初始化映射2
Map merged=Stream.concat(
map1.entrySet().stream(),map2.entrySet().stream()
)
.collect(collector.toMap)(
Map.Entry::getKey,
Map.Entry::getValue,
(v1,v2)->{v1.addAll(v2);返回v1;}//假设集合不是不可变的
));
这里有一种方法。虽然我使用了一些流处理来准备一些演示数据,但我在最终解决方案中避免了它,以保持处理更高效(基于我的测试),因为我不知道地图的大小
我还修改了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);
现在创建itemNamesAndIds
映射
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);
创建一个目标映射并简单地迭代类型和名称,创建
如果名称存在于itemNamesAndIds
映射中,则该名称的条目<代码>计算机发送
创建目标集
(如果尚未存在)
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);
数据对象
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;
}
}
让我们看看你试过什么。。。给你一个答案很容易,但你是如何找到答案的?你的方法有什么问题?这些都是我们可以帮助您解决的问题。不确定为什么要关闭此窗口以获取详细信息或澄清。这很清楚OP想要什么。我同意你关于流/效率的评论。很好的回答谢谢你。如果我有两张地图
Map
,如果我想合并它们,该怎么做?我尝试了putIfAbsent,但它只检查ItemType,而不检查ItemId.id。有什么建议吗?
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<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;
}
}