java treeset 排序,如何使用java8流对TreeSet的列表进行排序

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> block;

for(TreeSet t : block){

block.stream().sorted((n,m)->n.compareTo(m)).collect(Collectors.toSet());

}

The end result I want is [1,2,3][4,5,6].

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?

UPDATE:

List list=new ArrayList();

for(TreeSet t : block){

for(T t1 : t)

{

list.add(t1);

}

}

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

This works but could this be simplified?

解决方案

@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> 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 Collector>> partitioning(int size) {

class Acc {

int count = 0;

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

}

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.

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.

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.

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.

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值