Is there a way to coalesce repeated numbers in a list using streams in Java 8?

后端 未结 3 1084
长发绾君心
长发绾君心 2021-02-06 12:06

e.g.#1 [1, 1, 1, 2, 22, 35, 35, 120, 320] ==>> [3, 2, 22, 70, 120, 320]

note how repeated consecutive 1\'s and 35\'s are coalesced to 3 and 70

3条回答
  •  长发绾君心
    2021-02-06 12:54

    Stream.of(1, 1, 1, 2, 22, 35, 35, 120, 320)
              .collect(Collectors.toMap(
                  Function.identity(),
                  Function.identity(),
                  Integer::sum,
                  LinkedHashMap::new
              ))
              .values()
              .forEach(System.out::println);
    

    In the case the you posted a comment, you would need a custom collector, actually:

    static class Custom implements Collector, List> {
    
        private Integer match;
    
        @Override
        public Supplier> supplier() {
            return ArrayList::new;
        }
    
        @Override
        public BiConsumer, Integer> accumulator() {
            return (list, x) -> {
                int lastIndex = list.size() - 1;
                if (match != null && match.equals(x)) {
                    list.set(lastIndex, list.get(lastIndex) + x);
                } else {
                    match = x;
                    list.add(x);
                }
            };
        }
    
        @Override
        public BinaryOperator> combiner() {
            return (left, right) -> {
                throw new RuntimeException("Not for parallel");
            };
        }
    
        @Override
        public Function, List> finisher() {
            return Function.identity();
        }
    
        @Override
        public Set characteristics() {
            return Set.of();
        }
    }
    

    And usage would be:

    public static void main(String[] args) {
        Stream.of(1, 1, 3, 1, 1)
              .collect(new Custom())
              .forEach(System.out::println);
    }
    

提交回复
热议问题