如何优雅地删除List元素

2019-03-21  本文已影响0人  苏小小北

在使用ArrayList、LinkedList过程中,经常需要查找到其中某个元素,然后将该元素从列表中删除。最优雅的方式如下。

使用Iterator方式

        List<String> list = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            list.add(Integer.toString(i));
        }
        
        Iterator<String> iterator = list.iterator();

        while (iterator.hasNext()) {
            String str = iterator.next();
            if (str.equals("1")) {//删除值为1的元素
                iterator.remove();
            }
        }

除了上述的方式,还有其他的方式,但是都可能存在某些问题,需要慎用。

使用for(int i = 0; i < list.size(); i++)方式

        List<String> list = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            list.add(Integer.toString(i));
        }
        System.out.println("list 元素个数:" + list.size()); 
        // list 元素个数:10
        int j = 0; //用来记录遍历元素的个数
        for (int i = 0; i < list.size(); i++) {
            j++;
            if ("1".equals(list.get(i))) {
                list.remove("1");
            }
        }
        System.out.println("遍历到的元素个数为:" + j); 
        // 遍历到的元素个数为:9,少遍历了一个元素

发现并没有遍历所有的元素,因为list.remove后,导致列表元素个数和位置发生变化。

使用for(String s: list)增强的for循环方式

这种方式遍历时候,会抛出ConcurrentModificationException异常

        List<String> list = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            list.add(Integer.toString(i));
        }

        for (String s: list) {
            if ("1".equals(s)) {
                list.remove(s);
            }
        }

先看看增强for循环编译后代码内容

    List<String> list = new ArrayList();

    for(int i = 0; i < 10; ++i) {
      list.add(Integer.toString(i));
    }

    Iterator var4 = list.iterator();

    while(var4.hasNext()) {
      String s = (String)var4.next();
      if ("1".equals(s)) {
        list.remove(s);
      }
    }

实际上,增强的for循环也是用迭代器来实现的,这种方式与最上面方式的区别在于,删除的语句。

     private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        Itr() {}

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

expectedModCount:iterator对象中用来记录list对象修改的次数
modCount:list对象中用来记录list对象修改的次数

上一篇 下一篇

猜你喜欢

热点阅读