`
yznxing
  • 浏览: 367129 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

关于list的一个小知识

    博客分类:
  • java
 
阅读更多

最近咋使用  list.remove   方法的时候出了点问题。。。
贴出来,记录下。

public static void main(String[] args) {
        // TODO Auto-generated method stub
        List<Integer> list = new ArrayList();// =null error
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.add(7);
        list.add(8);
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) > 4)
                list.remove(i);
        }
        

        System.out.println(Arrays.toString(list.toArray()));

}

假定我们的代码如上。就是想把list里面大于4的值都remove掉,然后得到的list。
可是这个程序在运行后,会按照预期的值,打印出来的结果都是小于4的吗???

打印结果为:[1, 2, 3, 4, 6, 8]

答案是否定。主要是使用 i 下标在 list 内索引时,由于使用了remove会导致list内部的数组总值也就是length
变小,从而导致使用i在数组内索引时会导致空过一个元素。


解决办法有两个:
第一个将i从list.size()-1 开始索引,从后向前遍历就不会出问题的。
还有就是使用 迭代 Iterator 。

Iterator<Integer> it = list.iterator();
        while (it.hasNext()) {
            if (it.next() > 4) {
                it.remove();
            }
        }

这个可以主要是ArrayList内部的iterator返回的Iterator对象的remove方法在remove过之后会将当前索引值 减一。

相关内部实现为:

public void remove() {
        if (lastRet == -1)
        throw new IllegalStateException();
            checkForComodification();

        try {
        AbstractList.this.remove(lastRet);
        if (lastRet < cursor)
            cursor--;
        lastRet = -1;
        expectedModCount = modCount;
        } catch(IndexOutOfBoundsException e) {
        throw new ConcurrentModificationException();
        }
    }

从而可以成功的达到我们的目的。

 

 

1
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics