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

时间:2015-06-08 14:35:24

标签: java sorting collections

我在列表中有一个整数列表,并希望保留10个最大值,而我在迭代列表并将它们保存在TreeSet中。我正在使用此代码:

for(Integer i : list) {                
            if (treeSet.size() < 10) {                    
                treeSet.add(i);
            } else if (i > treeSet.last()) {
                treeSet.pollLast();
                treeSet.add(i);
            }
        }

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

4 个答案:

答案 0 :(得分:7)

'5,6,3,4,5,6' 按升序保存数据(第一个是最小的),所以你应该替换第一个元素,而不是最后一个:

treeSet

答案 1 :(得分:3)

使用Collection.sort()并使用List.subList()获得所需的结果数。

// Sort the arraylist
Collections.sort(list); 
//gets the last 10 item, last is the largest for ascending default sort
list.subList(list.size()-10, list.size());

答案 2 :(得分:1)

  

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

final Observable<MyDatum> observable = Observable.interval(10, TimeUnit.SECONDS).flatMap(new Func1<Long, Observable<MyDatum>>() {
    @Override
    public Observable<MyDatum> call(final Long counter) {
        return db.select("SELECT f1,f2 FROM mydata")
                .autoMap(MyDatum.class)
                .doOnNext(new Action1<MyDatum>() {
                    @Override
                    public void call(final MyDatum value) {
                        state.add(value);
                    }
                })
                .doOnCompleted(new Action0() {
                    @Override
                    public void call() {
                        state.makeAvailable();
                    }
                });
    }
});

final Subscription subscription = observable.subscribe();
     

返回

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

而不是

[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); 应该可以忽略不计。如果这个性能高度相关,可以考虑使用类似的方法和log(n),或者尝试优化这个解决方案,但是在目前的形式中,由于(过早的),它非常简单并且不容易出错。 )优化。

答案 3 :(得分:0)

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

final Comparator<Integer> order = Integer::compare;
List<Integer> collect = list.stream().sorted(order.reversed()).limit(10).sorted().collect(Collectors.toList());

你也可以使用parallelStream()而不是stream(),它应该更快。

http://blog.takipi.com/new-parallelism-apis-in-java-8-behind-the-glitz-and-glamour/