我正在寻找一种方法 Stream
一个List
进入Map
我可以在其中指定 key 。
例如,假设我有两个列表:
List<String> one = Arrays.asList("1","2","3");
List<String> two = Arrays.asList("100","200","300");
我正在寻找一种方法 Stream
他们变成Map<String, List<String>>
{
"below 100" : ["1","2","3"],
"above 100" : ["100","200","300"]
}
非常感谢任何帮助。到目前为止,这是我想出的:
Stream.of(
one.stream(),
.collect(Collectors.toMap("below 100", ??)
,
two.stream()
.collect(Collectors.toMap("above 100", ??)
)
.reduce(Stream::concat)
最佳答案
我发现了两种类似的方法。在这两种方式中,我们分别将每个 List 转换为 Map>,然后连接两个 Map。第一个选项较短并使用内联收集器,而第二个选项创建一个新的收集器类。
对于这两个选项,我们首先声明列表:
List<String> one = Arrays.asList("1", "2", "3");
List<String> two = Arrays.asList("100", "200", "300");
带有内联收集器的更短选项:
private BinaryOperator<List<String>> addToList() { return (list, str) -> { ((ArrayList<String>) list).addAll(str); return list; }; } Map<String, List<String>> map = Stream.of( // first list one.stream() .collect(Collectors.toMap( l -> "below 100", // we need List as map value l -> Stream.of(l).collect(Collectors.toList()), // merge function addToList(), // provide HashMap for result HashMap::new // we can't stream collected Map directly, only through EntrySet )).entrySet(), // second list two.stream() .collect(Collectors.toMap( l -> "above 100", l -> Stream.of(l).collect(Collectors.toList()), addToList(), HashMap::new )).entrySet() ) // extract Entry<String, List<String>> .flatMap(entrySet -> entrySet.stream()) // convert Entry<String, List<String>> to Map<String, List<String> .collect(Collectors.toMap( entry -> entry.getKey(), entry -> entry.getValue()));
使用自定义收集器的选项:
原始流代码较短,仅调用 ListToMapCollector 而不是实现内联收集器。
Map<String, List<String>> map = Stream
.of(
one.stream()
// use custom ListToMapCollector
.collect(new ListToMapCollector("below 100"))
// we can't stream collected Map directly, only through EntrySet
.entrySet(),
two.stream()
.collect(new ListToMapCollector("above 100"))
.entrySet())
// extract Entry<String, List<String>>
.flatMap(entrySet -> entrySet.stream())
// convert Entry<String, List<String>> to Map<String, List<String>
.collect(Collectors.toMap(
entry -> entry.getKey(),
entry -> entry.getValue()));
还有ListToMapCollector,我用了this tutorial创建时:
public class ListToMapCollector implements Collector<String, Map<String,
List<String>>, Map<String, List<String>>>
{
private String mapKey;
public TestCollector(String string)
{
this.mapKey = string;
}
@Override
public Supplier<Map<String, List<String>>> supplier() {
// provide HashMap for result
return HashMap::new;
}
@Override
public BiConsumer<Map<String, List<String>>, String> accumulator() {
return (map, stringValue) -> {
if (!map.containsKey(mapKey))
{
map.put(mapKey, new ArrayList<>());
}
map.get(mapKey).add(stringValue);
};
}
@Override
public BinaryOperator<Map<String, List<String>>> combiner() {
// Needed for parrallel stream, excluded for brevity.
return null;
}
@Override
public Function<Map<String, List<String>>, Map<String, List<String>>> finisher() {
return Function.identity();
}
@Override
public Set<java.util.stream.Collector.Characteristics> characteristics() {
return Collections.singleton(Characteristics.IDENTITY_FINISH);
}
}
关于java - 将列表值流式传输到 Map.Entry.values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39168813/