我有一个Stream<T>
,是否可以生成一个Map<T, Long>
,每个元素的计数增加一个?我还想将T, Long
转换为Long, T
,然后将其存储在Map
示例输入/输出中:
Stream<String>
的示例内容:
kgj
def
dgh
第一个问题的通缉输出:
(kgj, 1)
(def, 2)
(dgh, 3)
最终想要输出:
(1, kgj)
(2, def)
(3, dgh)
到目前为止,Stream<VertexData>
:
primitives.stream()
.flatMap(primitive -> primitive.getVertexData().stream())
.distinct()
.collect(Collectors.groupingBy(i -> i, Collectors.counting()))
.forEach((k, v) -> System.out.println("k = " + k + " / v = " + v));
目前这会将Stream<Primitive>
转换为具有不同元素的Stream<VertexData>
,然后转换为计算出现的Map<VertexData, Long>
,不< / strong>我想要什么,因为我希望继续计算每个传递的元素。
有办法做我的要求吗?
答案 0 :(得分:1)
你能做的就是编写自己的Collector
,为你计算遇到的元素。类似下面的工作:
Stream<String> strings = Stream.of("kgj", "def", "dgh");
strings.distinct().collect(Collector.of(
HashMap::new,
(BiConsumer<Map<String, Long>, String>) (map, str) -> {
map.put(str, Long.valueOf(map.size() + 1));
},
(left, right) -> {
long s = left.size();
right.entrySet().forEach(e -> left.put(e.getKey(),
Long.valueOf(
e.getValue()
.longValue()
+ s)));
return left;
})).forEach((k, v) -> System.out.println("k = " + k + " / v = " + v));
请注意,在并行处理流的情况下,需要(有点复杂的)组合器(Collector.of()
的第三个参数)。
答案 1 :(得分:1)
在@jpvee的启发下,我做了一个Collector
来回答问题的最后一个问题,并打算更清楚一点:
public static <T> Collector<T, ?, Map<Long, T>> indexing() {
return Collector.of(
HashMap::new,
(map, t) -> map.put(Long.valueOf(map.size() + 1), t),
(left, right) -> {
final long size = left.size();
right.forEach((k, v) -> left.put(k + size, v));
return left;
},
Collector.Characteristics.CONCURRENT
);
}
这是做什么的:
Stream<T>
上操作,它返回Map<Long, T>
,其中T
使用流的遭遇顺序对其进行索引。Collector.of
,正常情况下接受以下内容:
Map
的供应商。Map
添加一个元素。Map
。所以我提供的是:
Supplier<R>
:新的HashMap
。BiConsumer<R, T>
:一个获取地图并添加新元素的函数。BinaryOperator<R>
:组合两张地图的功能。Collector.Charasteristics
:此方法的特征,允许并发执行。