将流<t>映射到正在计数的地图<t,long =“”>?</t,> </t>

时间:2014-03-06 08:23:28

标签: java mapping java-8 java-stream

我有一个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>我想要什么,因为我希望继续计算每个传递的元素

有办法做我的要求吗?

2 个答案:

答案 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
    • charasteristics 的列表。

所以我提供的是:

  • Supplier<R>:新的HashMap
  • BiConsumer<R, T>:一个获取地图并添加新元素的函数。
  • BinaryOperator<R>:组合两张地图的功能。
  • Collector.Charasteristics:此方法的特征,允许并发执行。