2016-06-26 40 views
0

我有一个名为“玩家”的33个球员列表。他们都有不同的统计数据,我创建了比较这些统计数据的比较器。我想要做的是创建两个独立的阵列,获得前11名选手和底部11名选手。然后我可以根据这些进行不同的计算。这是我有什么:只把一部分集合放到一个数组中

Set<Player> ascending = new TreeSet<>(comparator); 
    Collections.addAll(ascending, players); 
    Player[] sorted = ascending.toArray(new Player[ascending.size()]); 
    Player[] topEleven = new Player[11]; 
    Player[] bottomEleven = new Player[11]; 
    for(int i=0;i<11;i++){ 
     topEleven[i]=sorted[i]; 
    } 
    for(int i=0,j=32;i<11;i++,j--){ 
     bottomEleven[i]=sorted[j]; 
    } 

这样的作品,但它很笨重,可能不是很有效。有一个更好的方法吗?

+0

使用https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#headSet(E,%20boolean)和 https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#tailSet(E) – Robert

+0

是否有任何具体原因使用数组而不是'java.util.List' ?如果没有,我会建议使用列表,而不是保存一些转换逻辑和列表来与许多便利的方法,将使您的生活更轻松。 – dpr

+0

@dpr:是的,我保持玩家名单非常有条理,并将玩家移动很多。选择过程由阵列中的特定位置(即玩家[12])使用。据我所知,这是不可能的列表。但我可能错了! –

回答

2

您可能需要使用Arrays.copyOfRange方法,像这样:

Set<Player> ascending = new TreeSet<>(comparator); 
Set<Player> descending = new TreeSet<>(comparator.reversed()); 
Collections.addAll(ascending, players); 
Collections.addAll(descending, players); 
Player[] topEleven = Arrays.copyOfRange(ascending.toArray(), 0, 10); 
Player[] bottomEleven = Arrays.copyOfRange(descending.toArray(), 0, 10); 

或者像@drp说,你可以使用List对象的subList方法。

0

你可以做这样的事情,如果你想坚持Set

final Player[] topEleven = new Player[11]; 
System.arraycopy(ascending.toArray(new Player[ascending.size()]), 0, topEleven, 
    0, topEleven.length); 

final Player[] bottomEleven = new Player[11]; 
System.arraycopy(descending.toArray(new Player[descending.size()]), 0, bottomEleven, 
    0, bottomEleven.length); 

或者你可以切换到使用List并做到这一点:

List<Player> ascending = new ArrayList<>(); 
Collections.addAll(ascending, players); 
ascending.sort(comparator) 
Player[] topEleven = ascending.subList(0, 10).toArray(new Player[11]); 
2

与Java 8中,您可以使用流:

Player[] topEleven = ascending.stream().limit(11).toArray(Player[]::new); 

此外,你可以使用流进行排序,因为它w on't修改原始players

Player[] topEleven = players.stream() 
          .sorted(comparator) 
          .limit(11) 
          .toArray(Player[]::new); 
+0

这是我正在寻找的确切效率。我只是没有得到很多流。不过,我一定要检查一下。使一切看起来更加快速和容易。 –

+0

在你的情况下它不会很重要,但与处理集合的“常用”方式相比,Java8流并不被认为是有效/快速的。 – dpr

+0

@dpr:由33名玩家组成的阵列,速度损失可以忽略不计,而代码可读性和简单性的提高非常大。此外,与您的解决方案相比,由于设置为流转换等同于'Collections.addAll',而两种解决方案均对数组进行排序和创建,因此完全没有任何损失。 – hoefling

相关问题