page contents

ArrayList截取问题

Pack 发布于 2020-02-17 15:26
阅读 558
收藏 0

List分割报错

测试

相关代码

public class SplitList {


/**

 * ArrayList分割问题

 */

@Test

public void splitList() {

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

    for (int i = 1; i < 10001; i ++) {

        list.add(i);

    }


    int init = 3000;

    int size = list.size();

    if (size > init) {

        int part = size / init;

        for (int j = 0; j < part; j ++ ) {

            List<Integer> partList = list.subList(0, init);

            list.subList(0, init).clear();

            ++System.out.println("被分割:" + partList);++

        }

        if (list != null && list.size() > 0) {

            System.out.println("分割后剩余长度:" + list.size());

            System.out.println("分割后剩余:" + list);

        }

    } else {

        //list长度小于要分割3000长度

        System.out.println("分割完成剩余:" + list);

    }

}

}


你期待的结果是什么?实际看到的错误信息又是什么?

注释掉line34就可以,求分析。

attachments-2020-02-ALR440GT5e4a402ae406e.pngattachments-2020-02-stHRNHa25e4a40332ba4d.png


379
Pack
Pack

如上异常清晰可见:


println入口,实际是String.valueOf(),这里会去找List的toString()

 attachments-2020-02-nWfV4iy75e4a4085db971.png

ArrayList本身没有实现toString()则使用父类AbstractCollection的toString();

 attachments-2020-02-Vy2xVDHR5e4a408e66f20.png

注意:迭代器则是ArrayList自己实现的

 attachments-2020-02-MTh00Tp85e4a409b105b2.png

顾名思义,回到了ArrayList,那么你这个partList已经被修改了,这里就会做checkForComodification检测,modCount与expectedModCount肯定是不相等的。

   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();

            }

        }


        @Override

        @SuppressWarnings("unchecked")

        public void forEachRemaining(Consumer<? super E> consumer) {

            Objects.requireNonNull(consumer);

            final int size = ArrayList.this.size;

            int i = cursor;

            if (i >= size) {

                return;

            }

            final Object[] elementData = ArrayList.this.elementData;

            if (i >= elementData.length) {

                throw new ConcurrentModificationException();

            }

            while (i != size && modCount == expectedModCount) {

                consumer.accept((E) elementData[i++]);

            }

            // update once at end of iteration to reduce heap write traffic

            cursor = i;

            lastRet = i - 1;

            checkForComodification();

        }


        final void checkForComodification() {

            if (modCount != expectedModCount)

                throw new ConcurrentModificationException();

        }

    }

请先 登录 后评论