java - 是否可以使用流将字符串分组并在有序的 Java 列表中对组成员进行计数?

标签 java java-stream

我有一个有序的字符串列表,比如说“aaa”,“aaa”,“aaa”,“bbb”,“bbb”,“aaa”。我想将相邻的相等字符串分组在一起并对它们进行计数,因此操作的结果应该是一个 List ,如下所示: {"aaa":3}, {"bbb": 2},{“aaa”,1}。请注意,任务不仅仅是按相同的值进行分组并对它们进行计数(否则我可以简单地将 groupingBycounting 一起使用),而是仅按具有相同值的相邻字符串进行分组值,如果相同的字符串稍后出现在列表中,则应将其视为单独的。基本上,我需要这段代码来从现有数据结构中创建一个具有适当列跨度的表头。

我想知道是否有一种相当好的方法可以使用 Java 8 流来完成此任务。我知道如何使用老式循环来做到这一点,只是认为流可能提供了更好的方法。

最佳答案

据我所知,您可以创建一个自定义收集器,但它与循环没有太大区别(将应用相同的逻辑)。另请注意,我使用 SimpleEntry 而不是 Pair 来保存列表中的每个元素。

private static Collector<String, ?, List<AbstractMap.SimpleEntry<String, Integer>>> adiacentCollector() {

    class Acc {

        private String previous;

        private List<AbstractMap.SimpleEntry<String, Integer>> result = new ArrayList<>();

        void accumulate(String elem) {
            if (previous == null) {
                previous = elem;
                result.add(new AbstractMap.SimpleEntry<String, Integer>(elem, 1));
                return;
            }

            if (previous.equals(elem)) {
                SimpleEntry<String, Integer> current = result.get(result.size() - 1);
                current.setValue(current.getValue() + 1);
                previous = elem;
            } else {
                SimpleEntry<String, Integer> oneMore = new SimpleEntry<String, Integer>(elem, 1);
                result.add(oneMore);
                previous = elem;
            }
        }

        Acc combine(Acc other) {

            SimpleEntry<String, Integer> lastEntry = result.get(result.size() - 1);
            SimpleEntry<String, Integer> firstEntry = other.result.get(0);

            if (lastEntry.getKey().equals(firstEntry.getKey())) {
                lastEntry.setValue(lastEntry.getValue() + firstEntry.getValue());
                other.result.remove(0);
            }

            result.addAll(other.result);

            return this;

        }

        List<AbstractMap.SimpleEntry<String, Integer>> finisher() {
            return result;
        }

    }
    return Collector.of(Acc::new, Acc::accumulate, Acc::combine, Acc::finisher);
}

并使用它:

 System.out.println(Stream.of("aaa", "aaa", "aaa", "bbb", "bbb", "aaa")
            .collect(adiacentCollector()));

关于java - 是否可以使用流将字符串分组并在有序的 Java 列表中对组成员进行计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45998611/

相关文章:

java - [Java][POI]将 EMF 图像插入 HSSFWorkbook

java - java中使用抽象类的方法重载的困惑

java - Vaadin Binder 中的上传组件,例如粗略编辑器

java - 我如何消费可选列表的每个元素?

java - 循环java 8时从列表中返回对象

java - gson 的 json 和包装器

java - 递增多个嵌套 While 循环

java - 如何在返回带条件的 boolean 值的方法上使用流

java - 计算多篇文章中的关键字出现次数

Java 8 Streams - 分层排序嵌套列表