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