【问题标题】:How to reduce usage of List in the code?如何减少代码中 List 的使用?
【发布时间】:2015-05-18 04:57:08
【问题描述】:

我有一个像这样的 EnumSet,所以要随机播放元素,我需要将其转换为 List。

EnumSet<Fruit> otherFruits = EnumSet.complementOf(CURRENT_FRUIT);

下面是我的代码,我在其中进行洗牌并将其添加到原始result 列表中:

private static List<Fruits> getFruits() {
    EnumSet<Fruits> local = EnumSet.of(CURRENT_FRUIT);
    // first element in the list will always be the local fruit so using LinkedList
    List<Fruits> result = new LinkedList<Fruits>(local);

    // I just want to shuffle remoteFruits only
    EnumSet<Fruit> otherFruits = EnumSet.complementOf(CURRENT_FRUIT);
    List<Fruits> remoteFruits = new ArrayList<Fruits>(otherFruits);
    Collections.shuffle(remoteFruits, new Random(System.nanoTime()));

    result.addAll(remoteFruits);
    return result;
}

到目前为止,我在上面的代码中使用了两个列表,然后将remoteFruits 列表的所有元素添加到result 列表中。有没有办法在一个列表中完成所有这些事情?我只想随机播放otherFruits 元素。

这里有优化的机会吗?

【问题讨论】:

  • 无关:你应该使用new Random()而不是new Random(System.nanoTime())
  • 你可以在 remoteFruits 的开头添加 CURRENT_FRUIT 洗牌后。
  • @immibis new Random()new Random(System.nanoTime()) 有什么区别吗?为什么你建议第一个?
  • 那么,你为什么要使用比它可能的随机性更小的种子呢? (而且:如果他们想出一种更随机的生成种子的方法,那么如果您使用 new Random(),您将免费获得改进)
  • 无关:你应该使用 Collections.shuffle(remoteFruits); 而不使用任何 Random 参数(它已经为你使用了一个 Random 实例,并且这样做更有效,因为它缓存了它。

标签: java list collections enums set


【解决方案1】:

确实,只要改变动作的顺序就可以做到:

private static List<Fruits> getFruits() {
    EnumSet<Fruits> local = EnumSet.of(CURRENT_FRUIT);
    EnumSet<Fruit> otherFruits = EnumSet.complementOf(CURRENT_FRUIT);

    // start by adding and shuffling otherFruits
    List<Fruits> result = new ArrayList<Fruits>(otherFruits)
    Collections.shuffle(result, new Random(System.nanoTime()));

    // now add local
    result.addAll(new ArrayList<Fruits>(local));
    return result;
}

【讨论】:

  • 感谢您的帮助。这个result.addAll(new ArrayList&lt;Fruits&gt;(local));会把本地水果加到LinkedList的顶部吗?
  • 不要试图创建 LinkedList 来洗牌;性能极差。使用 ArrayList。
  • @ErwinBolwidt 在这里的性能没有太大区别,因为:“如果指定的列表没有实现 RandomAccess 接口并且很大,则此实现在洗牌之前将指定的列表转储到一个数组中,并转储将数组改组回列表中”。见:(docs.oracle.com/javase/6/docs/api/java/util/…, java.util.Random)
  • @alfasin 我猜您最近的更改不会将local 添加到LinkedList 的顶部,对吧?我刚试过。
  • 我刚试过。它也不适用于 LinkedList 选项。我的意思是它不会将本地添加到 LinkedList 的顶部。知道为什么吗?
【解决方案2】:

您应该能够做到以下几点:

List<Fruits> list = Arrays.asList(Fruits.values());
Collections.shuffle(list);
return list;

不要认为有必要拥有 EnumSet、许多 List,或者为 shuffle 定义自己的随机源。

【讨论】:

    【解决方案3】:

    试试这样的:

        EnumSet<Fruits> fruits = EnumSet.allOf(Fruits.class);
        List<Fruits> result = new ArrayList<Fruits>(fruits);
        Collections.shuffle(result, new Random(System.nanoTime()));
    
        int idx = result.indexOf(CURRENT_FRUIT);
        if (idx != 0) {
            Fruits tmp = result.get(0);
            result.set(0, CURRENT_FRUIT);
            result.set(idx, tmp);
        }
    
        return result;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 2022-01-23
      相关资源
      最近更新 更多