Iterator接口也是Java集合框架的成员,但它与Collection系列、Map系列的集合不一样:

  • Collection系列集合、Map系列集合主要用于盛装其他对象,
  • Iterator对象也被称为迭代器,Iterator主要用于遍历(即迭代访问)Collection集合中的元素

Iterator接口隐藏了各种Collection实现类的底层细节,向应用程序提供了遍历Collection集合元素的统一编程接口。

Iterator接口方法

Iterator接口里定义了如下4个方法

方法 描述
boolean hasNext() 如果被迭代的集合元素还没有被遍历完,则返回true
Object next() 返回集合里的下一个元素
void remove() 删除集合里上一次next方法返回的元素
void forEachRemaining(Consumer action) 这是Java 8Iterator新增的默认方法,该方法可使用Lambda表达式来遍历集合元素
## 程序示例 ##
下面程序示范了通过Iterator接口来遍历集合元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.*;

public class 
{
public static void main(String[] args)
{ Collection books = new HashSet();
books.add("轻量级Java EE企业应用实战");
books.add("疯狂Java讲义");
books.add("疯狂Android讲义");
// 获取books集合对应的迭代器
Iterator it = books.iterator();
while(it.hasNext())
{
// it.next()方法返回的数据类型是Object类型,因此需要强制类型转换
String book = (String)it.next();
System.out.println(book);
if (book.equals("疯狂Java讲义"))
{
// 从集合中删除上一次next方法返回的元素
it.remove();
}
// 对book变量赋值,不会改变集合元素本身
book = "测试字符串"; //①
}
System.out.println("集合中的数据:"+books);
}
}

运行效果:

1
2
3
4
疯狂Android讲义
轻量级Java EE企业应用实战
疯狂Java讲义
集合中的数据:[疯狂Android讲义, 轻量级Java EE企业应用实战]

Iterator仅用于遍历集合

从上面代 大专栏  8.2.2 使用Java8增强的Iterator遍历集合元素码中可以看出, Iterator仅用于遍历集合, Iterator本身并不提供盛装对象的能力。如果需要创建Iterator对象,则必须有一个被迭代的集合。

Iterator必须依附于Collection对象

Iterator必须依附于Collection对象,若有一个Iterator对象,则必然有一个与之关联的Collection对象。 Iterator提供了两个方法来迭代访问Collection集合里的元素,并可通过remove()方法来删除集合中上一次next()方法返回的集合元素。

修改迭代变量的值对集合元素本身没有任何影响

当使用Iterator对集合元素进行迭代时, Iterator并不是把集合元素本身传给了迭代变量,而是把集合元素的值传给了迭代变量,所以修改迭代变量的值对集合元素本身没有任何影响

Iterator迭代时不可通过 其他方式 Collection集合里的元素

当使用Iterator迭代访问Collection集合元素时:

  • 不可以通过集合对象修改Collection集合里的元素,例如:不能通过集合对象添加元素,也不能通过集合对象添加元素。
  • 如果要删除元素,只有通过Iterator对象的的remove方法才可以删除next()方法返回的集合元素.
  • 否则将会引发java.util.ConcurrentModificationException异常。

程序示例

下面程序示范了这一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.*;

public class IteratorErrorTest {
public static void main(String[] args) { Collection<String> collection = new HashSet<String>();
collection.add("1");
collection.add("2");
collection.add("3");
collection.add("4");
// 获取books集合对应的迭代器
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()) {
String book = iterator.next();
System.out.println(book);
if (book.equals("3")) {
// 使用Iterator迭代过程中,不可以通过 集合对象 修改集合
// collection.remove(book);
collection.add("5");
// 只有Iterator对象的remove方法才可以删除遍历的元素
// iterator.remove();
}
}
}
}

运行效果:

1
2
3
4
5
6
7
1
2
3
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493)
at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1516)
at IteratorErrorTest.main(IteratorErrorTest.java:14)

上面程序中collection.remove(book);这行代码位于Iterator迭代块内,也就是在Iterator迭代Collection集合过程中修改了Collection集合,所以程序将在运行时引发异常。

Iterator迭代器采用的是快速失败(fail-fast)机制,一旦在迭代过程中检测到该集合已经被修改(通常是程序中的其他线程修改),程序立即引发ConcurrentModificationException异常,而不是显示修改后的结果,这样可以避免共享资源而引发的潜在问题。

原文链接: 8.2.2 使用Java8增强的Iterator遍历集合元素

8.2.2 使用Java8增强的Iterator遍历集合元素的更多相关文章

  1. java8 增强的Iterator遍历集合元素

    Iterator接口也是Java集合框架的成员,与Collection和Map两个系列的集合不一样的是Collection和Map系列主要用于充当容器的作用,而Iterator正如其名字一样是主要用于 ...

  2. 迭代器:遍历集合元素的操作. iterator()

    package seday11; import java.util.ArrayList;import java.util.Collection;import java.util.Iterator; / ...

  3. Java SE之For增强与Iterator遍历器提取数据(附Map.Entry)

    增强for循环: 1.操作数组 2.操作List集合 3.操作Map集合    1.map.values()法    2.map.keySet()法  [传统方法]    3.Map.Entry法   ...

  4. 增强for循环遍历集合或数组

    遍历:for循环遍历数组或集合:iterator迭代器遍历集合:还有增强for循环(for each)遍历数组或集合: 遍历数组: 遍历集合:

  5. 使用增强for循环遍历集合的时候操作集合的问题?

    // 遍历一个list public static void printList(List<String> list){ for (String string : list) { list ...

  6. 集合—collection、iterator遍历集合

    一.collection接口 1.collection常用方法 点击查看代码 @Test public void test(){ //contains() Collection coll = new ...

  7. iterator取集合元素

    1,完整代码 //创建两个arraylist对象 Collection al = new ArrayList(); //al1添加元素 al.add("name1"); al.ad ...

  8. java 数据类型:集合接口Collection之常用ArrayList;lambda表达式遍历;iterator遍历;forEachRemaining遍历;增强for遍历;removeIf批量操作集合元素(Predicate);

    java.util.Collection接口 Java的集合主要由两个接口派生出来,一个是Collection一个是Map,本章只记录Collection常用集合 集合只能存储引用类型数据,不能存储基 ...

  9. java集合(3)-Java8新增的Stream操作集合

    Java8新增了Stream,IntStream,LongStream,DoubleStream等流式API,这些API代表多个支持串行和并行聚集操作的元素.上面的4个接口中,Stream是一个通用的 ...

随机推荐

  1. ZJNU 1372 - 破解情书

    取模运算在数组内循环解密,否则会MLE /* Written By StelaYuri */ #include<stdio.h> ],cn[]; int main() { int i,j, ...

  2. 利用tensorflow编写自己的机器学习模型主要步骤

    利用tensorlow编写自己的机器学习模型主要分为两个阶段: 第一阶段:建立模型或者建立网络结构 1.定义输入和输出所需要的占位符 2.定义权重 3.定义具体的模型接口 4.定义损失函数 5.定义优 ...

  3. POJ 1734 Sightseeing trip(Floyd)

    题目传送门 题目中文翻译: Description 桑给巴尔岛上的阿德尔顿镇有一家旅行社,它已决定为其客户提供除了许多其他名胜之外的景点.为了尽可能地从景点赚取收入,该机构已经接受了一个精明的决定:有 ...

  4. C# List引用类型的克隆

    有时候我们想克隆一个List去做别的事,而不影响原来的List,我们直接在list后面加上小点点,发现并没有Clone这样的扩展函数.这时候就只有自己扩展了. 尝试了三种方式,测试都通过了,至于性能方 ...

  5. 五、Shell脚本高级编程实战第五部

    一.条件表达式 在bash的各种流程控制结构中通常要进行各种测试,然后根据测试结果执行不同的操作.有时也和if结合,让我们方便判断. test: 1)判断文件是否存在:test -f  file 2) ...

  6. Patroni 修改配置

    Patroni 修改配置 背景 使用 Patroni 部署 postgresql 集群的时候,不能单独修改单点的配置,这里需要通过 Patroni 来修改配置. 修改步骤 1. 修改 postgres ...

  7. 吴裕雄--天生自然TensorFlow高层封装:Keras-多输入输出

    # 1. 数据预处理. import keras from keras.models import Model from keras.datasets import mnist from keras. ...

  8. java 中的小数点、大数、随机数处理

    1.小数点处理 public class Test { public static void main(String[] args) { double i = 3.856; // 舍掉小数取整 Sys ...

  9. UML-词汇表

    样例:

  10. SpringMVC访问出错No converter found for return value of type

    在使用SSM整合的时候,spring mvc 添加@ResponseBody的时候,正常情况下都会返回json的.但是又的时候如果没有配置好的话,如果想要返回Map的json对象会报:No conve ...