我刚开始学习Java编程,之前一直在使用PHP,所以我习惯了这种类型的循环:
int size = mapOverlays.size();
for(int n=1;n<size;n++)
{
mapOverlays.remove(n);
}
所以我想删除除了第一个项目之外的所有内容,那么为什么这不起作用?按照我的理解,在删除后,数组键重新排列了吗?
我刚开始学习Java编程,之前一直在使用PHP,所以我习惯了这种类型的循环:
int size = mapOverlays.size();
for(int n=1;n<size;n++)
{
mapOverlays.remove(n);
}
所以我想删除除了第一个项目之外的所有内容,那么为什么这不起作用?按照我的理解,在删除后,数组键重新排列了吗?
你可以使用
mapOverlays.subList(1, mapOverlays.size()).clear();
removeRange
,并且基本上与Plamena的解决方案完全相同。主要区别在于方法调用的数量以及循环的位置。通过良好的JIT,我认为它们的性能相当类似。显然,它们的大O表示法是相同的。 - Matthew Flaschen我的理解是,在删除数组元素后,数组键会重新排列吗? 是的,当你移除在位置1的元素后,原来在位置2的元素将会被排到位置1。
你可以尝试这个方法:
Object obj = mapOverlays.get(0); // remember first item
mapOverlays.clear(); // clear complete list
mapOverlays.add(obj); // add first item
为什么不尝试倒着做呢?
(内容涉及IT技术)int size = itemizedOverlay.size();
for(int n=size-1;n>0;n--)
{
mapOverlays.remove(n);
}
ArrayList
。据我所知,对于Java内置的所有列表,包括LinkedList
,时间复杂度都是O(n)
。 - Matthew FlaschenArrayList
是一个整数索引从0到size() - 1
的集合。你可以这样做:
int size = mapOverlays.size();
for(int n=1;n<size;n++)
{
mapOverlays.remove(1);
}
clear()
或按相反的顺序进行操作。removeRange
是受保护的,因为这种操作会很方便。removeRange
方法(问题不在于它是受保护的,而是它甚至不存在于 List
接口中(这是正确的))。请参考 Adam Crune 的回答。 - Kevin BourrillionList
接口,所以那是一个非必然的推论。你可以争论他应该使用List
接口,但也许他确定他明确想要一个基于数组的类来获得其性能特性。 - Matthew Flaschen我认为创建一个只包含第一个元素的新ArrayList会更快。可以像这样实现:
E temp = mapOverlays.get(0);
mapOverlays = new ArrayList<E>().add(temp);
add
returns a boolean
, so you can’t do mapOverlays = new ArrayList<E>().add(temp);
You need two statements, mapOverlays = new ArrayList<E>();
and mapOverlays.add(temp);
- HolgermapOverlays = Collections.singletonList(mapOverlays.get(0));
因为在ArrayList
中,第一个元素的索引是0
在Java中正确的方式是:
while( mapOverlays.size() > 1 ) {
mapOverlays.remove( mapOverlays.size() - 1 );
}
java.util.List
实现而不是数组,则每次删除元素时数组的大小都会变小,n+1
项将替换n
项。当n
变得大于列表中的最后一个索引时,此代码最终将导致ArrayIndecOutOfBoundsException
。Object[] mapOverlay = //initialize the array here
int size = mapOverlay.length;
for(int n=1;n<size;n++)
{
mapOverlay[n] = null;
}
我不懂 PHP,但这听起来很接近你想要的行为。然而,List 实现比数组更灵活、更舒适。
编辑:这里是 List.remove(int)
的 Javadoc 链接:http://java.sun.com/javase/6/docs/api/java/util/List.html#remove%28int%29
int size = mapOverlays.size();
for(int n=0;n<size;n++)
{
mapOverlays.remove(n);
}
while (mapOverlays.size() > 1) {
mapOverlays.remove(1);
}
编辑(请参见Adam Crume的评论)
如果性能是一个问题,您应该使用这个。
while (mapOverlays.size() > 1) {
mapOverlays.remove(mapOverlays.size()-1);
}
即使是一点微小的优化
int last = mapOverlays.size() - 1;
while (last >= 1) {
mapOverlays.remove(last);
last -= 1;
}
sublist
解决方案。虽然它有点难以阅读,但如果列表实例无法重新创建(在其他地方引用),那么这可能是最快的解决方案。remove(1)
的解决方案仍然比 O(n^2) 更糟糕,但我更喜欢它用于小列表的可读性更高(依我之见)- 问题根本没有提到性能。sublist
解决方案优雅且更好(最佳),但不是每个人都理解如何使用 sublist
。 - user85421remove(1)
解决方案对于小列表可能很好,但我认为最好拥有适用于任何列表的代码。 - Adam Crume