使用Java 8流

时间:2017-08-29 14:10:34

标签: java list java-8

首次问问提问者,请放轻松。 :)无论如何,我不确定使用Java 8流是否可行,但我对学习非常感兴趣。

假设我有以下有序的数字列表:

List<Integer> myList = Arrays.asList(1, 2, 3, 7, 9, 12, 13, 15);

现在,当元素之间的差异大于2时,我想将此列表拆分为多个列表。因此,最终结果将是三个不同的列表:

{1, 2, 3}
{7, 9}
{12, 13, 15}

我可以使用for循环轻松完成此练习,并将当前元素与之前循环时的元素进行比较。但是,我想知道是否有一种使用Java 8流来实现这一目标的简洁方法?就像我之前说的那样,这只是为了我自己对Java 8的学习和理解,所以如果不可能那就没关系。

提前感谢任何意见或答案。

2 个答案:

答案 0 :(得分:4)

嗯,我只能想到一个自定义收集器,因为你需要一些以前的状态,但这到目前为止并不简洁(除非你把它隐藏在一个方法后面):

 private static <T> Collector<Integer, ?, List<List<Integer>>> diffCollector() {

    class Acc {

        private Integer previous;

        private List<List<Integer>> result = new ArrayList<>();

        void accumulate(Integer elem) {
            if (previous == null) {
                previous = elem;
                List<Integer> list = new ArrayList<>();
                list.add(previous);
                result.add(list);
                return;
            }

            if (elem - previous > 2) {
                List<Integer> oneMore = new ArrayList<>();
                oneMore.add(elem);
                result.add(oneMore);
                previous = elem;
            } else {
                result.get(result.size() - 1).add(elem);
                previous = elem;
            }
        }

        Acc combine(Acc other) {

            throw new UnsupportedOperationException("Not for parallel");
        }

        List<List<Integer>> finisher() {
            return result;
        }

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

使用方法是:

 List<Integer> myList = Arrays.asList(1, 2, 3, 7, 9, 12, 13, 15);
 System.out.println(myList.stream().collect(diffCollector()));

答案 1 :(得分:0)

在不创建/实现收藏家和减少行

的情况下即兴创作@Eugene答案
    List<Integer> e = Arrays.asList(1,2,3,7,9,12,14,15);
    List<Integer> grpMarker = new ArrayList<>();
    grpMarker.add(0);
    grpMarker.add(0);

    Collection<List<Integer>>  o = e.stream().collect(Collectors.groupingBy(s-> {
        if (s - grpMarker.get(0) > 2) { grpMarker.add(1,grpMarker.get(1)+1); }
        grpMarker.remove(0);
        grpMarker.add(0,s);
        return grpMarker.get(1);
    })).values();
    System.out.println(o);

grpMarker是启动器,用于跟踪最后一个元素(索引0)和任意组值(索引1)。