我有类似的东西
Object[] myObjects = ...(initialized in some way)...
int[] elemToRemove = new int[]{3,4,6,8,...}
从myObjects中删除索引位置3,4,6,8的元素的最有效方法是什么?
我想用像
这样的签名实现一个有效的效用方法 public Object[] removeElements(Object[] object, int[] elementsToRemove) {...}
返回的Object []应该是一个大小为myObjects.length的新对象 - elemToRemove.length
答案 0 :(得分:3)
您无法从Java
数组中删除元素。你能做的是:
Collections
。答案 1 :(得分:2)
您需要创建一个新数组,因为数组的大小不会改变(在保持相同数组时不能“移除”元素,它会在某处创建漏洞)。我建议这个:
Object[] nobjs = Arrays.copyOf(myObjects, myObjects.length - elemToRemove.length);
for (int i = 0, j = 0, k = 0; i < myObjects.length; i ++) {
if (j < elemToRemove.length && i == elemToRemove[j]) {
j ++;
} else {
nobjs[k ++] = myObjects[i];
}
}
这假定elemToRemove
已经排序,没有重复,并且只包含在源数组中有效的索引。 Arrays.copyOf()
调用仅用于确保新数组的运行时类型与源数组的运行时类型相同。
如果您经常需要从数组中“删除”数据,因此需要创建新数组,那么Java数组可能不是最有效的数据结构。 LinkedList
或ArrayList
可能更合适。
答案 2 :(得分:1)
如果你想频繁删除它的元素,我建议你使用LinkedList而不是数组。
使用数组(array-&gt;链表 - &gt;删除元素 - >数组)实现它也很容易,但效率不高:
我认为,最有效的方法(如果你仍然想使用数组)是创建只有旧数组中必需元素的新数组:
Object[] filteredObjects = new Object[myObjects.length - elemToRemove.length];
int j = 0;
for (int i = 0; i < myObjects.length; i++) {
if (!shouldRemove(i)) {
filteredObjects[j++] = myObjects[i];
}
}
myObjects = filteredObjects;
我没有展示shouldRemove
。我认为你应该创建一组索引而不是elemToRemove
数组(索引是唯一的,所以它在任何情况下都是首选方式)。然后shouldRemove
可以更改为elemToRemove.contains(i)
。
可以建议您使用Google Collections的另一种方式(我不确定它是否有效但对我来说看起来很优雅):
for (int index : elemToRemove) {
myObjects[i] = null;
}
myObjects = Collections2.filter(Arrays.asList(myObjects), new Predicate<Object>() {
@Override
public boolean apply(Object obj) {
return obj!= null;
}
}).toArray();
答案 3 :(得分:1)
Java数组是不可变的,你不能只是删除项目而不会在中间留下漏洞。
你可以做的是首先删除所有元素的出现,然后通过填充所有孔来压缩阵列;顺便说一句,这是非常低效的。否则,您可以为正确的元素创建一个新数组,但是您需要先知道它的大小..
你能做的最好的事情就是使用一个LinkedList
,它可以通过排除物体而不产生任何洞来移除物体,它们只是从结构中消失。然后,您可以使用Collection.toArray(..)
获取新阵列。
答案 4 :(得分:0)
如果您有要修改的阵列,那么我建议使用各种集合类,例如LinkedList或ArrayList。常规数组无法调整大小,因此您不能简单地添加/删除元素。
但是,假设您有两个数组Object[] myObjects
和Object[] toRemove
,并且您需要一个函数返回一个新数组,其中toRemove
中的元素从myObjects
中删除:
public static Object[] remove(Object[] myObjects, Object[] toRemove)
{
HashSet<Object> tr = new HashSet<Object>();
tr.addAll( Arrays.asList(toRemove) );
List<Object> removed = new ArrayList<Object>();
for(Object o : myObjects)
if( !tr.contains(o) )
removed.add(o);
return removed.toArray();
}