我希望使用java流将Collection<Placement>
转换为Map<String, Collection<String>>
,其中Placement
类如下所示
public class Placement {
private String id;
/* Links two placements, may be same for atleast 2 placements. */
private String futureLinkId;
}
地图的关键是未来的链接ID,值是放置ID。例如,如果有2个展示位置
p1 { id=1, futureLinkId=f1 }, p2 { id=2, futureLinkId=f1 }
,输出应为Map { f1 - { id1, id2 } }
答案 0 :(得分:3)
这实际上非常简单,尽管其他人提供了令人费解的解决方案:
Map<String, List<String>> map = placements.stream()
.collect(groupingBy(Placement::getFutureLinkId, mapping(Placement::getId, toList())));
答案 1 :(得分:0)
您只需按futureLinkId
分组,然后将值映射到id
。写它的一种方法:
Map<String, List<String>> result = Stream.of(new Placement("id1", "f1"), new Placement("id2", "f1"))
.collect(Collectors.groupingBy(Placement::getFutureLinkId))
.entrySet()
.stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().stream().map(Placement::getId).collect(Collectors.toList())));
System.out.println(result);
输出:
{f1=[id1, id2]}
为了让它看起来更漂亮,我建议写两个帮手:
public static <K, V, N> Map<K, N> mapValues(Map<K, V> map, Function<V, N> mapper) {
return map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, mapper.compose(Map.Entry::getValue)));
}
public static <T, R> List<R> map(List<T> list, Function<T, R> mapper) {
return list.stream().map(mapper).collect(toList());
}
然后
Map<String, List<String>> result = Stream.of(new Placement("id1", "f1"), new Placement("id2", "f1")).collect(
collectingAndThen(groupingBy(Placement::getFutureLinkId),
res -> mapValues(res, list -> map(list, Placement::getId))));
System.out.println(result);
答案 2 :(得分:0)
使用three-argument toMap
是实现所需目标的一种方式。 (groupingBy
似乎是另一个,但我并不熟悉该方法。)
对于toMap
,您需要一个将Placement
映射到键的函数;将Placement
映射到某个值的函数,在这种情况下,该值必须是 set 值;最后一个函数将两个值合并在一起,如果它们具有相同的键。像
Map<String,HashSet<String>> result =
placements.stream()
.collect(Collectors.toMap
(placement -> placement.futureLinkId,
placement -> new HashSet(Collections.singleton(placement.id)),
(s1, s2) -> { HashSet<String> result = new HashSet<>(s1);
result.add(s2);
return result; }));
注意:我还没有对此进行过测试。如果流是顺序流,则可以在不复制s1
的情况下工作。