【问题标题】:Only putting part of a set to an array仅将集合的一部分放入数组
【发布时间】:2016-06-26 18:49:37
【问题描述】:

我有一个名为“球员”的 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];
    }

这行得通,但是它很笨重并且可能效率不高。有没有更好的方法来做到这一点?

【问题讨论】:

  • 有什么特别的理由让你使用数组而不是java.util.List?如果不是,我建议您使用 List 代替,因为您可以节省一些转换逻辑,并且 List 带有许多方便的方法,可以让您的生活更轻松。
  • @dpr : 是的,我把球员名单组织得井井有条,并且经常移动球员。选择过程由数组中的特定位置(即,players[12])使用。据我所知,这对于列表是不可能的。但我可能是错的!
  • @ShaddAnderson 要么我错过了你的观点,要么你错过了java.util.List.get(n) 的方法。也许您将此与 java.util.Set 混淆了,后者不提供按索引访问元素的可能性。实际上,我使用数组而不是 List 的唯一情况是 vararg methods

标签: java arrays sorting set


【解决方案1】:

您可能希望像这样使用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方法。

【讨论】:

    【解决方案2】:

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

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

    此外,您可以使用流进行排序,因为它不会修改原始的players

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

    【讨论】:

    • 这正是我正在寻找的效率。我只是没有深入了解流。不过,我肯定要检查一下。让一切看起来更加快速和简单。
    • 在您的情况下可能无关紧要,但与处理集合的“通常”方式相比,Java8 流不被认为是高效/快速的。
    • @dpr:速度损失对于 33 名玩家来说可以忽略不计,而代码可读性和简单性的提高是巨大的。此外,与您的解决方案相比,完全没有损失,因为设置为流转换等效于Collections.addAll,而两种解决方案都排序并创建数组。
    【解决方案3】:

    如果你想坚持使用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]);
    

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 1970-01-01
      • 2016-12-25
      • 2011-07-21
      • 1970-01-01
      • 2016-09-28
      • 2021-12-10
      • 2021-06-02
      • 1970-01-01
      相关资源
      最近更新 更多