当前位置: 首页 > 知识库问答 >
问题:

我如何排序与java8流树集列表

尚嘉庆
2023-03-14

我的列表包含像[1,3,5][2,6,4]等大小相同的集合。我试过这样做,但似乎不起作用。

List<TreeSet<T>> block;
    for(TreeSet<T> t : block){
        block.stream().sorted((n,m)->n.compareTo(m)).collect(Collectors.toSet());

    }

我想要的最终结果是[1,2,3][4,5,6]

我可以尝试在ArrayList中添加所有元素,并对其进行排序,然后为TreeSet创建一个新的列表?

更新:

List<T> list=new ArrayList<T>();
    for(TreeSet<T> t : block){

        for(T t1 : t)
        {
            list.add(t1);   

        }
    }

    list=list.stream().sorted((n,m)->n.compareTo(m)).collect(Collectors.toList());

这是可行的,但可以简化吗?


共有3个答案

罗学林
2023-03-14

添加另一个答案,因为这将比评论更重要。这确实是被接受的答案所做的,但是使用了一个“更智能”的组合器,它不必一直流式传输。

 private static <T> Collector<T, ?, List<Set<T>>> partitioning(int size) {
    class Acc {
        int count = 0;

        List<List<T>> list = new ArrayList<>();

        void add(T elem) {
            int index = count++ / size;
            if (index == list.size()) {
                list.add(new ArrayList<>());
            }
            list.get(index).add(elem);
        }

        Acc merge(Acc right) {

            List<T> lastLeftList = list.get(list.size() - 1);
            List<T> firstRightList = right.list.get(0);
            int lastLeftSize = lastLeftList.size();
            int firstRightSize = firstRightList.size();

            // they have both the same size, simply addAll will work
            if (lastLeftSize + firstRightSize == 2 * size) {
                System.out.println("Perfect!");
                list.addAll(right.list);
                return this;
            }

            // last and first from each chunk are merged "perfectly"
            if (lastLeftSize + firstRightSize == size) {
                System.out.println("Almost perfect");
                int x = 0;
                while (x < firstRightSize) {
                    lastLeftList.add(firstRightList.remove(x));
                    --firstRightSize;
                }
                right.list.remove(0);
                list.addAll(right.list);
                return this;
            }

            right.list.stream().flatMap(List::stream).forEach(this::add);
            return this;
        }

        public List<Set<T>> finisher() {
            return list.stream().map(LinkedHashSet::new).collect(Collectors.toList());
        }

    }
    return Collector.of(Acc::new, Acc::add, Acc::merge, Acc::finisher);
}
谭景明
2023-03-14

如果类路径上有番石榴,这是一件轻而易举的事:

        block
            .stream()
            .flatMap(Set::stream)
            .collect(Collectors.toCollection(TreeSet::new));

    Iterable<List<Integer>> result = Iterables.partition(sorted, 3);
步骏
2023-03-14

@尤金的回答很甜,因为番石榴很甜。但是,如果您的课程路径中没有番石榴,那么还有另一种方法:

List<Set<Integer>> list = block.stream()
    .flatMap(Set::stream)
    .sorted()
    .collect(partitioning(3));

首先,我将所有集合平面映射到一个流中,然后对所有元素进行排序,最后,我将整个排序的流收集到集合列表中。为此,我将调用一个使用自定义收集器的助手方法:

private static <T> Collector<T, ?, List<Set<T>>> partitioning(int size) {
    class Acc {
        int count = 0;
        List<Set<T>> list = new ArrayList<>();

        void add(T elem) {
            int index = count++ / size;
            if (index == list.size()) list.add(new LinkedHashSet<>());
            list.get(index).add(elem);
        }

        Acc merge(Acc another) {
            another.list.stream().flatMap(Set::stream).forEach(this::add);
            return this;
        }
    }
    return Collector.of(Acc::new, Acc::add, Acc::merge, acc -> acc.list);
}

该方法接收每个分区的大小,并使用Acclocal类作为收集器要使用的可变结构。在Acc类中,我使用了一个列表,该列表将包含LinkedHashSet实例,它将保存流的元素。

Acc类保存已收集的所有元素的计数。在add方法中,我计算列表的索引并增加此计数,如果列表的该位置没有设置,我将向其添加一个新的空LinkedHashSet。然后,我将元素添加到集合中。

当我在流上调用sorted()以在收集之前对其元素进行排序时,我需要使用保留插入顺序的数据结构。这就是为什么我对外部列表使用ArrayList,对内部列表使用LinkedHashSet

并行流将使用merge方法合并两个先前累积的Acc实例。我只是将收到的Acc实例的所有元素添加到此Acc实例中,方法是委托add方法。

最后,我使用的是收集器。of以基于Acc类的方法创建收集器。最后一个参数是finisher函数,它只返回Acc实例的列表。

 类似资料:
  • 问题内容: 我的清单包含大小等的集合。我尝试这样做,但似乎不起作用。 我想要的最终结果是。 我可以尝试添加在所有的元素和那种出来再做出新的的。但是,有某种班轮吗? 更新: 这可行,但是可以简化吗? 问题答案: @Eugene的回答很甜蜜,因为番石榴很甜。但是,如果您碰巧在类路径中没有番石榴,这是另一种方式: 首先,我将所有集合映射到一个流中,然后对所有元素进行排序,最后,将整个排序后的流收集到集合

  • 问题内容: 我正在使用Java lambda对列表进行排序。 如何以相反的方式对其进行排序? 我看到了这篇文章,但是我想使用java 8 lambda。 这是我的代码(我用* -1)作为破解 问题答案: 您可以调整在Java中如何以降序对ArrayList 排序的方法中链接的解决方案通过将其包装在lambda中: 请注意, f2 是的第一个参数,而不是第二个,因此结果将相反。

  • 我有一个订单列表,我想使用Java8Stream和Collectors按用户分组。GroupingBy: 这将返回包含用户和订单列表的映射: 我不需要整个对象User,只需要它的username字段,它是一个字符串,所以我想获得如下内容: 我试图使用stream.map将用户映射到username字段,但无法正确实现。我怎样才能尽可能简单地做到这一点呢?

  • 我正在使用java lambda对列表进行排序。 我怎样才能反向排序呢?

  • 我有map,我想有一个列表,它按键的对应值排序(最小到最大)。我的尝试是:

  • 哦,那些狡猾的Java8条带有lambdas的溪流。它们非常强大,但是复杂的东西需要一点时间来包裹它。 假设我有一个类型,其属性为。假设我有这些用户的地图 ?