概述
概述:
迭代器模式:就是提供一种方法对一个容器对象中的各个元素进行访问,而又不暴露该对象容器的内部细节。
Java集合框架的集合类,我们有时候称之为容器。容器的种类有很多种,比如ArrayList、LinkedList、HashSet...,每种容器都有自己的特点,ArrayList底层维护的是一个数组;LinkedList是链表结构的;HashSet依赖的是哈希表,每种容器都有自己特有的数据结构。
因为容器的内部结构不同,很多时候可能不知道该怎样去遍历一个容器中的元素。所以为了使对容器内元素的操作更为简单,Java引入了迭代器模式!
把访问逻辑从不同类型的集合类中抽取出来,从而避免向外部暴露集合的内部结构。
为什么要引入迭代器的概念?
对于数组我们使用的是下标来进行处理的:
int array[] = new int[3];
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
对ArrayList的处理:
List<String> list = new ArrayList<String>();
for(int i = 0 ; i < list.size() ; i++){
String string = list.get(i);}
对于这两种方式,我们总是都知道它的内部结构,访问代码和集合本身是紧密耦合的,无法将访问逻辑从集合类和客户端代码中分离出来。不同的集合会对应不同的遍历方法,客户端代码无法复用。所以才有Iterator,它总是用同一种逻辑来遍历集合。所有的内部状态都由Iterator来维护。客户端不用直接和集合进行打交道,而是控制Iterator就可以遍历集合,从而避免向外部暴露集合的内部结构。
代码实现:
在Java中Iterator为一个接口,它只提供了迭代的基本规则。迭代器在迭代期间可以从集合中移除元素(必须使用迭代器的删除方法)。
其接口定义如下:
public interface Iterator<E> {
boolean hasNext();//判断是否存在下一个对象元素
E next();//获取下一个元素
void remove();//移除元素
}
使用迭代器遍历集合:
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("张三1");
list.add("张三2");
list.add("张三3");
list.add("张三4");
List<String> linkList = new LinkedList<String>();
linkList.add("link1");
linkList.add("link2");
linkList.add("link3");
linkList.add("link4");
Set<String> set = new HashSet<String>();
set.add("set1");
set.add("set2");
set.add("set3");
set.add("set4");
//使用迭代器遍历ArrayList集合
Iterator<String> listIt = list.iterator();
while(listIt.hasNext()){
System.out.println(listIt.hasNext());
}
//使用迭代器遍历Set集合
Iterator<String> setIt = set.iterator();
while(setIt.hasNext()){
System.out.println(listIt.hasNext());
}
//使用迭代器遍历LinkedList集合
Iterator<String> linkIt = linkList.iterator();
while(linkIt.hasNext()){
System.out.println(listIt.hasNext());
}
}
Iterator遍历时不可以删除集合中的元素:
import java.util.*; //导包
public class Test1 {
public static void main(String[] args)
{
ArrayList <Clerk> al=new ArrayList<>(); //创建集合
al.add(new Clerk("周卫国",30,5000)); //添加对象
al.add(new Clerk("李云龙",30,5000));
al.add(new Clerk("诸葛亮",30,5000));
al.add(new Clerk("张小凡",30,5000));
al.add(new Clerk("泛型",30,5000));
al.add(new Clerk("集合",30,5000));
System.out.println("---------遍历集合");
Iterator <Clerk> listIt = al.iterator(); //创建迭代器
while(listIt.hasNext()) //遍历
{
Clerk temp = listIt.next();
if(temp.getName().equals("李云龙"))//找到李云龙
al.remove(1); //删除对象
//或者是a1.add(new Clerk("1",2,3)) //又或者是添加对象
}
System.out.println("---------输出集合");
for(Clerk x:al)
{
System.out.println(x.getName()+" "+x.getAge()+" "+x.getSalary());
}
}
}
class Clerk //定义员工类
{
private String name;
private int age;
private double salary;
Clerk(String name,int age,double salary)
{
this.name=name;
this.age=age;
this.salary=salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
输出结果:
---------遍历集合
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at text.Test1.main(Test1.java:17)
在使用Iterator的时候禁止对所遍历的容器进行改变其大小结构的操作。例如: 在使用Iterator进行迭代时,如果对集合进行了add、remove操作就会出现ConcurrentModificationException异常。
因为在你迭代之前,迭代器已经被通过list.itertor()创的,就会给出善意的提醒(抛出ConcurrentModificationException异常)建出来了,如果在迭代的过程中,又对list进行了改变其容器大小的操作,那么Java就会给出异常。因为此时Iterator对象已经无法主动同步list做出的改变,Java会认为你做出这样的操作是线程不安全
使用Foreach时对集合的结构进行修改会出现异常:
因为foreach要依赖于Iterable接口返回的Iterator对象,所以从本质上来讲,Foreach其实就是在使用迭代器,在使用foreach遍历时对集合的结构进行修改,和在使用Iterator遍历时对集合结构进行修改本质上是一样的,所以同样的也会抛出异常。
最后
以上就是甜蜜发箍为你收集整理的Java——深入理解Java中的迭代器的全部内容,希望文章能够帮你解决Java——深入理解Java中的迭代器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复