我需要保持唯一可见的元素列表,并且还需要不时从它们中随机选择一个。我有两种简单的方法可以做到这一点。

  • 保持元素在集合中可见-这使我具有独特的元素。如果需要随机选择一个,请执行以下操作:
    elementsSeen.toArray()[random.nextInt(elementsSeen.size())]
    
  • 保持元素在列表中可见-这种方式无需转换为数组,因为当我需要随机数时,可以使用get()函数。但是在添加时,我需要这样做。
    if (elementsSeen.indexOf(element)==-1) {elementsSeen.add(element);}
    

  • 所以我的问题是哪种方法会更有效?转换为数组更耗费资源还是indexOf更糟?如果尝试添加元素的次数增加10或100或1000次怎么办?

    我对如何以最有效的方式将列表(按索引访问)的功能与集合(唯一添加)的功能结合在一起感兴趣。

    最佳答案

    如果使用更多内存不是问题,那么可以通过使用列表和包装器中的两个方法来充分利用两者:

    public class MyContainer<T> {
        private final Set<T> set = new HashSet<>();
        private final List<T> list = new ArrayList<>();
    
        public void add(T e) {
            if (set.add(e)) {
                list.add(e);
            }
        }
    
        public T getRandomElement() {
            return list.get(ThreadLocalRandom.current().nextInt(list.size()));
        }
        // other methods as needed ...
    }
    

    07-24 09:50
    查看更多