简介:
在之前对集合的输出使用的是Iterable接口中的forEach()方法,但是这中方法并不是传统的输出方法,在开发之中一般是不适用的。
在集合之中一共定义有四种输出形式【使用比率】:
- Iterator迭代输出 【95%】
- ListIterator双向迭代输出 【0.1%】
- Enumeration枚举输出 【4.9%】
- foreach输出 【与Iterator相当】
Iterator输出:
通过Collection接口的继承关系可以发现,从JDK1.5开始其多继承了一个Iterable父接口,并且在这个接口中定义有iterator()操作方法,通过此方法可以获取Iterator对象(在JDK1.5之前,这一方法直接定义在Collection接口中)
- 获取Iterator接口对象:Iterator<T> iterator();
在Iterator接口中定义有如下方法:
NO. |
方法名称 |
类型 |
功能 |
1 |
public boolean hasNext();
|
普通 | 判断是否有数据 |
2 |
public E next();
|
普通 | 取出当前数据 |
3 |
public default void remove()
|
普通 | 删除(一般不使用) |
在之前使用的java.util.Scanner类就是Iterator接口的子类。
使用Iterator输出:
import java.util.Iterator;
import java.util.Set;
public class MAIN {
public static void main(String[] args) {
Set<String> set = Set.of("Hello","World","China");
Iterator<String> iter = set.iterator(); //实例化Iterator接口对象
while(iter.hasNext()) {
String str = iter.next();
System.out.println("str: " + str);
}
}
}
输出结果:
但是对于Iterator接口中的remove()方法需要特别注意,如果不是必须不要使用。
在Collection接口中定义有删除操作方法,但是在进行迭代输出的过程里面如果你使用了Collection中的remove()方法会导致迭代失败。
采用Collection接口中的remove()方法:
package Demo_3_14_集合的输出; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class MAIN { public static void main(String[] args) { Set<String> all = new HashSet<String>(); all.add("Hello"); all.add("World"); all.add("MLDN"); Iterator<String> iter = all.iterator(); while (iter.hasNext()) { String str = iter.next(); if ("World".equals(str)) { all.remove("World"); }else { System.out.println(str); } } } }
输出结果:
Hello
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1597)
at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1620)
at Demo_3_14_集合的输出.MAIN.main(MAIN.java:15)
出现了并发修改异常。
采用Iterator接口中的remove()方法:
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class MAIN {
public static void main(String[] args) {
Set<String> all = new HashSet<String>();
all.add("Hello");
all.add("World");
all.add("MASN");
Iterator<String> iter = all.iterator();
while (iter.hasNext()) {
String str = iter.next();
if ("World".equals(str)) {
iter.remove();
}else {
System.out.println(str);
}
}
}
}
输出结果:
成功删除元素。
面试题:
请解释Collection.remove()与Iterator.remove()的区别?
在进行迭代输出的时候,如果使用了Collection.remove()则会造成并发更新的异常,导致程序删除出错,
而此时只能够利用Iterator接口中remove()方法实现正常的删除处理。
再次强调:不是必须不要使用remove()方法。
ListIterator双向迭代输出:
Iterator进行迭代的输出操作有一个特点:只允许由前向后实现输出,而如果现在想要实现双向迭代处理,就需要用到ListIterator;
如果想要获取ListIterator接口对象,在Collection接口中并没有定义相关方法,但是List接口有,可以说ListIterator输出接口是专门为List集合准备的;
ListIterator接口里定义有:
- 判断是否有前一个元素:public boolean hasPrevious();
- 获取当前元素:public E previous();
代码实现:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; public class MAIN { public static void main(String[] args) { List<String> all = new ArrayList<String>(); all.add("Hello"); all.add("World"); all.add("China"); all.add("China"); all.add("China"); ListIterator<String> iter = all.listIterator(); System.out.print("由前向后输出:"); while(iter.hasNext()) { System.out.print(iter.next() + " "); } System.out.print("\n由后向前输出:"); while(iter.hasPrevious()) { System.out.print(iter.previous() + " "); } }
输出结果:
如果想要由后向前遍历,那么肯定会有一个由前向后遍历的过程,必须要先由前向后判断是否有元素,找到最后一个元素后,再从最后一个元素开始由后向前遍历。
例如下面的代码没有由前向后的遍历,只有由后向前:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class MAIN {
public static void main(String[] args) {
List<String> all = new ArrayList<String>();
all.add("Hello");
all.add("World");
all.add("China");
all.add("China");
all.add("China");
ListIterator<String> iter = all.listIterator();
System.out.print("\n由后向前输出:");
while(iter.hasPrevious()) {
System.out.print(iter.previous() + " ");
}
}
输出结果:
可以发现输出的结果没有任何东西。
Enumeration枚举输出:
Enumeration是在JDK1.0的时候就使用的输出接口,这个输出接口主要是为Vector类服务,在后续JDK的发展中Enumeration依旧是为Vector类服务,如果想要获取Enumeration接口对象,就必须依靠Vector类提供的方法;
- 获取Enumeration: public Enumeration<E> elements();
在Enumeration接口中定义有:
- 判断是否有下一个元素:public boolean hasMoreElements();
- 获取当前元素:public E nextElement();
代码实现:
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
public class MAIN {
public static void main(String[] args) {
Vector<String> vector = new Vector<String>();
vector.add("Hello");
vector.add("World");
vector.add("China");
Enumeration<String> en = vector.elements();
while(en.hasMoreElements()) {
System.out.print(en.nextElement() + " ");
}
}
}
输出结果;
大部分时候都是使用Iterator中的方法就行了。
foreach输出:
除了使用迭代接口实现输出,从JDK1.5开始加强型for循环也可以实现集合的输出;
这种输出的形式与数组的输出形式类似;
代码实现:
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
public class MAIN {
public static void main(String[] args) {
List<String> all = new ArrayList<String>();
all.add("Hello");
all.add("World");
all.add("China");
for(String str : all) {
System.out.print(str + " ");
}
}
}
输出结果:
集合的标准输出应该是使用Iterator中的方法进行输出,但是使用这种方式输出也无妨。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)