Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-没有迭代器分配就没有重复的集合_Java_Memory Management_Game Engine - Fatal编程技术网

Java-没有迭代器分配就没有重复的集合

Java-没有迭代器分配就没有重复的集合,java,memory-management,game-engine,Java,Memory Management,Game Engine,问题 我正在开发一个游戏,我需要最小化内存分配和GC活动。为此,我需要一个具有非重复值的集合,以最小化访问操作期间的内存分配。我准备妥协,稍微降低性能,以弥补改进后的“垃圾生成” 考虑的解决方案(包括废弃的供参考) 扩展ArrayList以在add(E)中包含重复项的检查,如果值存在,则不执行任何操作。(这也可能包括其他方法) 使用HashSet(丢弃)-元素的迭代会导致新迭代器的实例化,从而在访问过程中不需要最小的内存分配 将HashSet转换为ArrayList(已丢弃)比HashSet迭代

问题

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

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

  • 扩展ArrayList以在add(E)中包含重复项的检查,如果值存在,则不执行任何操作。(这也可能包括其他方法)
  • 使用HashSet(丢弃)-元素的迭代会导致新迭代器的实例化,从而在访问过程中不需要最小的内存分配
  • 将HashSet转换为ArrayList(已丢弃)比HashSet迭代创建更多的内存分配
  • 问题

    扩展ArrayList以防止重复值是否是以最小内存分配实现非重复收集的合理方法?是否有其他方法我应该考虑?

    注释

    我所见过的消除ArrayList中重复项的大多数建议解决方案都是使用HashSet或其他对象实例化,它们不符合我的最小内存分配要求。我能想到的唯一实现是ArrayList的基本“for迭代”,它根据每个现有元素检查附加值的相等性

    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);
        }
    }
    
    类非重复列表扩展了ArrayList{
    @凌驾
    布尔加法(E){
    对于(int i=0;i
    这里的不是
    列表
    :,根据合同,必须返回
    true

    返回:

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

    您可以抛出一个
    IllegalArgumentException

    抛出:

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

    但是必须处理异常是很糟糕的

    此外,扩展
    ArrayList
    很少是正确的做法:在这种情况下,
    ArrayList
    s允许您在末尾添加任何元素(前提是有足够的内存),因此您的类不会被Liskov替换

    另外,当然,您必须覆盖所有其他允许您向列表添加元素的方法:
    add
    (其他重载)、
    addAll
    set
    、子列表上的所有方法和
    列表迭代器
    等。这很难正确执行


    相反,使用组合:

    类非重复列表{
    私有最终列表委托=新建ArrayList();
    布尔加法(E){
    //contains更容易!ArrayList.contains不使用迭代器。
    if(delegate.contains(e))返回false;
    返回委托。添加(e);
    }
    //您可能需要的其他方法
    }
    

    通过这样定义您自己的类,您不必遵守您自己没有设计的任何契约;而且您可以公开更小的方法集,使维护列表的无重复属性的工作量大大减少。

    一个
    迭代器
    对象在内存方面相当便宜。我想知道您是否不去结论和要求太快。@davidxxx“相当便宜”,但在游戏环境中(大量访问操作和低延迟要求)总而言之,我很欣赏人们对这种小生境问题的怀疑,但总体目标是在游戏框架生命周期中获得接近零的分配,通常你会通过汇集/重用对象来实现这一点,这对于迭代器来说是一个相当大的问题。旁注如果内存使用是一个大问题,你可能想考虑使用LINKEDLIST,这样你就不会有任何调整大小的操作。@ Todoy感谢-不太关心内存占用,对LINKEDLIST与ARARYLIST的决定可能会受到访问性能(读取/插入)的驱动。以个案为基础,而不是以内存为基础。谢谢,这一概念的实现确实更清晰。我实现了无重复ArrayList解决方案(通过组合),取代了基于迭代器的访问,GC暂停图现在是一条漂亮的直线:-)
    
    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
    }