Java-没有重复分配的无重复集合

时间:2019-02-20 14:13:43

标签: java memory-management game-engine

问题

我正在开发一个游戏,需要最小化内存分配和GC活动。为此,我需要一个具有非重复值的集合,以最小化访问操作期间的内存分配。我准备妥协以稍微降低性能来弥补改进的“垃圾生成”。

考虑的解决方案(包括废弃的解决方案供参考)

  1. 扩展ArrayList ,包括对 add(E e)进行重复检查,如果值存在则不执行任何操作。 (这可能还包括其他方法)
  2. 使用HashSet(丢弃)-元素的迭代会导致实例化新的Iterator,从而消除了访问期间最小内存分配的要求。
  3. 将HashSet转换为ArrayList(丢弃)-比HashSet迭代创建更多的内存分配。

问题

ArrayList的扩展是防止重复值的一种明智的方法,它可以以最小的内存分配来实现非重复收集吗?我应该考虑替代方法吗?

注释

大多数消除ArrayList中重复项的建议解决方案,我看到是指使用HashSet或其他对象实例化而无法满足我的最小内存分配要求。我能想到的唯一实现是ArrayList的基本“迭代”功能,用于检查每个现有元素的附加值是否相等。

Class NonDuplicateList extends ArrayList{
    @Override
    boolean add(E e){
        for(int i = 0; i < this.size(); i++){
            if(this.get(i).equals(e)
                return false;
        }
        return super.add(e);
    }
}

1 个答案:

答案 0 :(得分:2)

您这里没有List:根据合同,List.add必须返回true

  

返回:

     

true(由Collection.add(E)指定)

您可以投掷IllegalArgumentException

  

投掷:

     

IllegalArgumentException-如果此元素的某些属性阻止将其添加到此列表中

但是必须处理异常是很严重的。

另外,扩展ArrayList很少的正确做法:在这种情况下,ArrayList s允许您将任何元素添加到末尾(只要有足够的内容内存),因此您的课程不会被Liskov替代。

此外,当然,您必须重写所有其他用于将元素添加到列表的方法:add(其他重载),addAllsetsubListlistIterator等上的所有方法,等等。这很难正确完成。


相反,请使用组成

class NonDuplicateList<E> {
    private final List<E> delegate = new ArrayList<>();

    boolean add(E e){
        // contains is easier! ArrayList.contains does not use an iterator.
        if (delegate.contains(e)) return false;
        return delegate.add(e);
    }

    // Other methods you may require
}

通过这样定义自己的类,不需要遵循未设计的任何合同;而且您可以公开更小的方法集,从而减少维护列表的no-duplicates属性的工作量。