Java 8,整数流,按整数对流的索引进行分组?

标签 java dictionary java-8 java-stream

我得到了一个整数流,我想根据每个元素的值对元素的索引进行分组。
例如,{1, 1, 1, 2, 3, 3, 4} 被分组为 Integer 到索引映射列表:

1 -> 0, 1, 2
2 -> 3
3 -> 4, 5
4 -> 6

我试过使用流,但有一个额外的类:

@Test
public void testGrouping() throws Exception {
    // actually it is being read from a disk file
    Stream<Integer> nums = Stream.of(1, 1, 1, 2, 3, 3, 4);  
    // list to map by index
    int[] ind = {0};  // capture array, effectively final
    class Pair {
        int left;
        int right;

        public Pair(int left, int right) {
            this.left = left;
            this.right = right;
        }
    }

    Map<Integer, List<Integer>> map = nums.map(e -> new Pair(ind[0]++, e))
            .collect(Collectors.groupingBy(e -> e.right))
            .entrySet().parallelStream()
            .collect(Collectors.toConcurrentMap(
                    Map.Entry::getKey,
                    e -> e.getValue().parallelStream().map(ee -> ee.left).collect(Collectors.toList())
            ));
}

我必须读取 Stream,因为 Integer 流是从我的应用程序中的磁盘文件中读取的。
我觉得我按照上面的方式做这件事是非常次优的。有没有更好或更优雅的方法来做到这一点?
谢谢你的帮助。

最佳答案

使用一些辅助方法来收集:

class MapAndIndex {
    Map<Integer,List<Integer>> map=new HashMap<>();
    int index;

    void add(int value) {
        map.computeIfAbsent(value, x->new ArrayList<>()).add(index++);
    }
    void merge(MapAndIndex other) {
        other.map.forEach((value,list) -> {
            List<Integer> l=map.computeIfAbsent(value, x->new ArrayList<>());
            for(int i: list) l.add(i+index);
        } );
        index+=other.index;
    }
}

整个操作变成:

Map<Integer,List<Integer>> map = IntStream.of(1, 1, 1, 2, 3, 3, 4)
    .parallel()
    .collect(MapAndIndex::new, MapAndIndex::add, MapAndIndex::merge).map;

当您需要跟踪事先未知的索引时,您需要可变状态,因此需要调用 “mutable reduction” 操作.

注意这里不需要ConcurrentMapStream 实现将已经处理并发。它将为每个相关线程创建一个 MapAndIndex 容器,并在两个相关线程完成工作后对两个容器调用 merge 操作。这也将以保留顺序的方式完成,如果 Stream 有一个顺序,就像在这个例子中一样(否则你记录索引的任务没有意义......)。

关于Java 8,整数流,按整数对流的索引进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27980488/

相关文章:

java - Java 8 的默认垃圾收集器

java - addToBackStack(null) 中的 null 的目的是什么?

java - Keycloak - 自定义 SPI 未出现在列表中

java - Gradle/Java 替换文本

java - 如何避免时差为负时间?

python字典日期时间作为键,keyError

Python 按值排序字典可能不稳定? (在 Hackerrank 中)

python - Jinja 使用 for 列出嵌套 JSON

Java 8 : Convert List<ObjectA> into List<ObjectB> by grouping and summing over different fields using streams

java - 对 Object.clone() 的功能引用不编译