gpt4 book ai didi

java - 如何使用 java8 流对 TreeSets 列表进行排序

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:05:39 32 4
gpt4 key购买 nike

我的列表包含像 [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。但是是否存在某种单一的衬垫?

更新:

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 很甜。但是如果你碰巧在类路径中没有 Guava,还有另一种方法:

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

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

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

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

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

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

关于java - 如何使用 java8 流对 TreeSets 列表进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44337530/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com