如何在java中读取列表时保持10个最大整数?

如何在java中读取列表时保持10个最大整数?,java,sorting,collections,Java,Sorting,Collections,我在一个列表中有一个整数列表,我希望在遍历该列表时保留最大的10个整数,并将它们保留在树集中。我正在使用以下代码: for(Integer i : list) { if (treeSet.size() < 10) { treeSet.add(i); } else if (i > treeSet.last()) {

我在一个列表中有一个整数列表,我希望在遍历该列表时保留最大的10个整数,并将它们保留在树集中。我正在使用以下代码:

for(Integer i : list) {                
            if (treeSet.size() < 10) {                    
                treeSet.add(i);
            } else if (i > treeSet.last()) {
                treeSet.pollLast();
                treeSet.add(i);
            }
        }
用于(整数i:list){
如果(treeSet.size()<10){
添加(i);
}else if(i>treeSet.last()){
treeSet.pollLast();
添加(i);
}
}

但当我在运行此代码之前更改列表中整数的顺序时,结果是不同的。我的代码是真的吗?

treeSet
按升序保存其数据(第一个是最小的),因此您应该替换第一个元素,而不是最后一个:

for(Integer i : list) {                
    if (treeSet.size() < 10) {                    
        treeSet.add(i);
    } else if (i > treeSet.first()) {
        treeSet.pollFirst();
        treeSet.add(i);
    }
}
用于(整数i:list){
如果(treeSet.size()<10){
添加(i);
}else if(i>treeSet.first()){
treeSet.pollFirst();
添加(i);
}
}
使用并获得所需数量的结果

尝试使用streams(如果可以使用Java 8):

最终比较器顺序=整数::比较;
List collect=List.stream().sorted(order.reversed()).limit(10.sorted().collect(Collectors.toList());
您还可以使用parallelStream()代替stream(),后者应该更快

警告:请注意,您的方法通常存在缺陷(并且该缺陷也存在于最初接受的答案中):当列表中存在重复元素时,这可能会产生错误的结果。一个随机的例子,我注意到这是一个输入列表,如

List<Integer> list = Arrays.asList(
     0, 8, 9, 7, 15, 13, 11, 1, 19, 14, 
     17, 17, 13, 2, 15, 4, 4, 15, 1, 0); 
而不是

[4, 7, 8, 9, 11, 13, 14, 15, 17, 19]

简单、直接的解决方案如下:

private static <T> Collection<T> keepLargest(
    List<? extends T> list, Comparator<T> comparator, int n)
{
    TreeSet<T> treeSet = new TreeSet<T>(comparator);
    for(T t : list) 
    {                
        treeSet.add(t);
        while (treeSet.size() > n)
        {
            treeSet.pollFirst();
        }
    }
    return treeSet;
}
private static Collection keepLargest(

列表侧注意:我假设
TreeSet
实际上是一个变量的名称-如果是这样的话:请花一些时间阅读“java编码指南”。变量名称以小写字母开头。在这种情况下,“偏差”从这个样式指南中,可能会导致许多错误的假设……感谢您的非@Jägermeister我更正了它。对于较大的列表,这将不是非常有益的,从性能角度来看:排序是
O(n*log(n))
,其中后一个“n”是列表的大小。对于插入/删除的目标集合,有
O(log(n))
,并且当目标集合的大小被限制在例如小的“k”时,算法的运行时间将为
O(n*log(k))
,其中
log(k)
基本上是一个小常数。
[1, 7, 8, 9, 11, 13, 14, 15, 17, 19]
[4, 7, 8, 9, 11, 13, 14, 15, 17, 19]
private static <T> Collection<T> keepLargest(
    List<? extends T> list, Comparator<T> comparator, int n)
{
    TreeSet<T> treeSet = new TreeSet<T>(comparator);
    for(T t : list) 
    {                
        treeSet.add(t);
        while (treeSet.size() > n)
        {
            treeSet.pollFirst();
        }
    }
    return treeSet;
}
Collection<Integer> kept = 
    keepLargest(list, Comparator.naturalOrder(), 10);