Lex*_*yte 7 java treeset java-8 java-stream
我的列表包含类似的集合[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());
}
Run Code Online (Sandbox Code Playgroud)
我想要的最终结果是[1,2,3][4,5,6].
我可以尝试添加在所有的元素ArrayList和那种出来再做出新List的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());
Run Code Online (Sandbox Code Playgroud)
这有效但可以简化吗?
Fed*_*ner 10
@ Eugene的答案很甜蜜,因为番石榴很甜.但是,如果您的类路径中没有Guava,这是另一种方式:
List<Set<Integer>> list = block.stream()
.flatMap(Set::stream)
.sorted()
.collect(partitioning(3));
Run Code Online (Sandbox Code Playgroud)
首先,我将所有集合平面化为一个流,然后我将所有元素排序,最后,我将整个排序流收集到集合列表中.为此,我正在调用一个使用自定义收集器的辅助方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
该方法接收每个分区的大小,并使用Acc本地类作为收集器使用的可变结构.在Acc类中,我使用的List是包含LinkedHashSet实例的实例,它将保存流的元素.
将Acc类保存所有已已收集到的元素的个数.在该add方法中,我计算列表的索引并递增此计数,如果列表的该位置没有设置,我LinkedHashSet向它添加一个新的空.然后,我将元素添加到集合中.
因为我sorted()在收集之前调用流来对其元素进行排序,所以我需要使用保留插入顺序的数据结构.这就是我ArrayList用于外部列表和LinkedHashSet内部集合的原因.
该merge方法由并行流使用,以合并两个先前累积的Acc实例.我只是通过委托给方法将所接收Acc实例的所有元素添加到此Acc实例中add.
最后,我正在使用Collector.of基于Acc类的方法创建一个收集器.最后一个参数是finisher函数,它只返回Acc实例的列表.