Iterable:可以说是站在集合框架最顶端的接口,实现集合的遍历。
最后才发现,这个接口里面要说的太少啦。好吧,我们重点就说说Iterator
Iterator:
方法就不在赘述,通过一个实际的例子来说明吧:
场景:我们需要在不新建对象的情况下,从源List删除指定的数据,最后打印出来:
其实从这个问题本身出发并不难,难就在于你从一开始就轻视它,最后结果就说明一切啦。也不卖什么关子啦,直接进入正题:
错误事例:
List sourceList = new ArrayList<>(Arrays.asList("a", "b", "a", "c", "d"));
for (int i = 0; i < sourceList.size(); i++) {
if (sourceList.get(i).equals("a")) {
sourceList.remove(sourceList.get(i));}
}
sourceList.forEach(System.out::println);
看结果简直perfect,但是确实暗中埋着深坑。当我发现第一个待移除元素的时候,从list移除掉,list.size发生变化,元素的索引也在变化。比如你循环到第2个元素的时候你把它删了,接下来你去访问第3个元素,实际上访问到的是原先的第4个元素。
解决方案1:
人为的维护下标,就能达到想要的效果。
List sourceList = new ArrayList<>(Arrays.asList("a", "a", "b", "a", "a", "a", "c", "d"));
for (int i = 0; i < sourceList.size(); i++) {
if (sourceList.get(i).equals("a")) {
sourceList.remove(sourceList.get(i));
i--; }
}
sourceList.forEach(System.out::print);
解决方案2:
这种方式就是借助迭代器实现List的动态删减。
⚠️:一定是Iterator的remove方法,还必须在next()方法后面使用,请看原文注释:
This method can be called only once per call to {@link #next}
关于具体实现,后续文章会具体说明
List sourceList = new ArrayList<>(Arrays.asList("a", "b", "a", "c", "d"));
Iterator iterator = sourceList.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
if (next.equals("a")) {
iterator.remove(); }
}
sourceList.iterator().forEachRemaining(System.out::println);
哈哈,突然发现这个例子把Iterator的所有方法用上了,也算是碰巧吧。