如何使用java8流对TreeSet的列表进行排序 [英] How do I sort a List of TreeSets with java8 streams

查看:745
本文介绍了如何使用java8流对TreeSet的列表进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My list contains sets like [1,3,5][2,6,4] etc, all of the same size. I tried doing this but it doesn't seem to work.

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]

我可以尝试添加<$ c中的所有元素$ c> ArrayList 并对其进行排序,然后创建一个新的 List TreeSet 's 。但是有一种衬垫吗?

I could try to add all the elements in an ArrayList and sort that out then make a new List of TreeSet's. But is there is some kind of one liner?

更新:

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());

这有效但可以简化吗?

推荐答案

@ Eugene的回答很甜蜜,因为番石榴很甜。但是如果你的类路径中没有Guava,这是另一种方式:

@Eugene's answer is sweet, because Guava is sweet. But if you happen to not have Guava in your classpath, here's another way:

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

首先,我将所有集合平面化为一个流,然后我将所有元素排序最后,我将整个排序的流收集到一组集合中。为此,我正在调用一个使用自定义收集器的辅助方法:

First, I'm flatmapping all the sets into one stream, then I'm sorting all the elements and finally, I'm collecting the whole sorted stream to a list of sets. For this, I'm invoking a helper method that uses a custom collector:

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);
}

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

The method receives the size of each partition and uses the Acc local class as the mutable structure to be used by the collector. Inside the Acc class, I'm using a List that will contain LinkedHashSet instances, which will hold the elements of the stream.

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

The Acc class keeps the count of all the elements that have been already collected. In the add method, I calculate the index of the list and increment this count, and if there was no set in that position of the list, I append a new empty LinkedHashSet to it. Then, I add the element to the set.

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

As I'm calling sorted() on the stream to sort its elements before collecting, I need to use data structures that preserve insertion order. This is why I'm using ArrayList for the outer list and LinkedHashSet for the inner sets.

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

The merge method is to be used by parallel streams, to merge two previously accumulated Acc instances. I'm just adding all the elements of the received Acc instance to this Acc instance, by delegating to the add method.

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

Finally, I'm using Collector.of to create a collector based on the methods of the Acc class. The last argument is a finisher function, which just returns the Acc instance's list.

这篇关于如何使用java8流对TreeSet的列表进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆