将 Map<K, List<V>> 转换为 Map<K, V> 其中 V 有 2 个对象列表
Posted
技术标签:
【中文标题】将 Map<K, List<V>> 转换为 Map<K, V> 其中 V 有 2 个对象列表【英文标题】:Convert Map<K, List<V>> to Map<K, V> where V have 2 lists of objects 【发布时间】:2022-01-23 19:49:24 【问题描述】:型号:
Year
int year;
ObjectB
ObjectBA bb; <- ObjectBAint value
ObjectBB ba; <- ObjectBBint value
ObjectC
List<ObjectBA>
List<ObjectBB>
如何转换:
Map<Year, List<ObjectB>>
到
Map<Year, ObjectC>
其中对象 C 具有来自 ObjectB 的所有元素
我已经有了:
var result = inputMap.entrySet().stream()
.collect(Collectors.toMap(
e -> e.getKey(),
e -> e.getValue().stream().
map(
value -> value.bb().getValue()
).toList())
);
我需要在 Object 中给我多个列表的东西,例如:
map(
new ObjectC(
value -> value.ba().getValue(),
value -> value.bb().getValue()
).toList())
【问题讨论】:
如果你有 Guava,那么使用ObjectC
的正确构造函数,你可以说 Maps.transformValues(inputMap, v -> new ObjectC(v.bb, v.ba));
。即使使用流,Guava 也有更清晰的方式来表达一些常见的操作。
【参考方案1】:
你所拥有的看起来已经很不错了。只需将值映射器替换为e -> convert(e.getValue())
,其中convert
就像下面将List<ObjectB>
转换为ObjectC
的函数:
ObjectC convert(List<ObjectB> list)
ObjectC c = new ObjectC();
for (ObjectB b : list)
c.ba.add(b.ba);
c.bb.add(b.bb);
return c;
或者,如果您更喜欢只使用流,请尝试Stream#collect
,如下所示:
e.getValue().stream().collect(
() -> new ObjectC(),
(c, b) ->
c.ba.add(b.ba);
c.bb.add(b.bb);
,
(c1, c2) ->
c1.ba.addAll(c2.ba);
c1.bb.addAll(c2.bb);
)
【讨论】:
非常感谢!也用于转换器。我会有很多这样的皈依者,所以它可能会有用! 如果你拥有并且可以修改ObjectC
类,我建议添加一个方便的方法 void add(ObjectB b) this.ba.add(b.ba); this.bb.add(b.bb);
这样你就不必到处重复了。【参考方案2】:
为了将来可能的参考,我提供以下内容:
第一个是基于循环的简单解决方案。在这两者中,这更直接而且可能更有效。
迭代地图的条目集。 创建两个列表,ObjectC
的每个字段一个
然后遍历 ObjectB
列表并将对象复制到它们的列表中
然后使用新创建的列表创建ObjectC
的实例
我使用了 getter 和 and 构造函数,但如果字段不是私有的,则可以使用直接赋值。
for (Year y : map.keySet())
List<ObjectBA> listBA = new ArrayList<>();
List<ObjectBB> listBB = new ArrayList<>();
for (ObjectB b : map.get(y))
listBA.add(b.getBA());
listBB.add(b.getBB());
result.put(y, new ObjectC(listBA, listBB));
此方法使用流。
流式传输 entrySet。 并使用构造函数创建一个新的 ObjectC。 构造函数的参数本身就是源列表的流 执行映射以获取对象(BA 和 BB) 并返回一个列表以满足构造函数的要求。Map<Year, Object> result = map.entrySet().stream().collect(
Collectors.toMap(Entry::getKey,
e -> new ObjectC(
e.getValue().stream().map(ObjectB::getBA)
.toList(),
e.getValue().stream().map(ObjectB::getBB)
.toList())));
【讨论】:
以上是关于将 Map<K, List<V>> 转换为 Map<K, V> 其中 V 有 2 个对象列表的主要内容,如果未能解决你的问题,请参考以下文章
番石榴:Set<K> + Function<K,V> = Map<K,V>?