java 使用subList痛彻心扉的领悟
背景
刚开始截取List集合时使用笨的方法自己截取,后来发现Java api 有方法使用 subList方法,但是由于不清楚原理拿来就用,做项目就掉坑里了
List<UclassUser> subList = list.subList(0, GameRoom.CAPACITY / 2); subList.forEach(item -> { item.setRoomId(newRoom.getId()); newRoom.getStuList().add(item.getUserId()); }); list.removeAll(subList); studentAlreadyList.addAll(subList);
就是这些代码报的错,大家可以自行去看
查看源码
原来subList方法是new 了一个SubList对象把原来的list引用传了进去,所以返回的SubList对象,SubList对象也只是源集合的影像,不是新的List,所以你要是操作源集合,那么就会报异常
throw new ConcurrentModificationException()
这种类型的异常 fail-fast,在Java中叫快速失败,有兴趣的可以去查资料
public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, 0, fromIndex, toIndex); } static void subListRangeCheck(int fromIndex, int toIndex, int size) { if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > size) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); } private class SubList extends AbstractList<E> implements RandomAccess { private final AbstractList<E> parent; private final int parentOffset; private final int offset; int size; SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) { this.parent = parent; this.parentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount; }
总结
最后解决办法用新的list去接受一下,就可以操作原来的集合了
List<UclassUser> subList = new ArrayList<>(list.subList(0, GameRoom.CAPACITY / 2)); subList.forEach(item -> { item.setRoomId(newRoom.getId()); newRoom.getStuList().add(item.getUserId()); }); list.removeAll(subList); studentAlreadyList.addAll(subList);
上一篇:
IDEA上Java项目控制台中文乱码