标签:直接 toe lock asn add turn string except 网上
迭代:Iterator,即collection集合元素的通用获取方式
java.util.Iterator接口。迭代器(对集合进行遍历)
有两个常用的方法
Boolean hasNext()如果仍有元素可以迭代,则返回true
判断集合中还有没有下一个元素,有就返回true,没有就返回false
E next()返回迭代的下一个元素
取出集合中的下一个元素
Iterator迭代器,是一个接口,我们无法直接使用,需要Iterator接口的实现类对象,获取实现类的方式比较特殊
Collection接口中有一个方法,叫Iterator(),这个方法返回的就是迭代器的实现类对象
Iterator iterator()返回在此collection的元素上进行迭代的迭代器
迭代器的使用步骤(重点)
1、使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
3、使用Iterator接口中的方法next取出集合中的下一个元素
package Iterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo01Collection {
public static void main(String[] args) {
//创建一个集合对象
Collection<String> coll=new ArrayList<>();
coll.add("星星");
coll.add("仰望星空");
coll.add("最美的太阳");
coll.add("这就是爱");
//1、使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
//Iterator<E>的接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型
//多态 接口 实现类对象
Iterator<String> it=coll.iterator();
//发现使用迭代器取出集合中元素的代码是一个重复的过程
//所以我们可以使用循环优化
//不知道集合中有多少元素,使用while集合
//循环结束的条件,hasNext方法返回false
while (it.hasNext()){
String e=it.next();
System.out.println(e);
}
// //2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
// boolean b=it.hasNext();
// System.out.println(b);//true
//
// // 3、使用Iterator接口中的方法next取出集合中的下一个元素
// String s=it.next();
// System.out.println(s);
//
// //2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
// b=it.hasNext();
// System.out.println(b);//true
// // 3、使用Iterator接口中的方法next取出集合中的下一个元素
// s=it.next();
// System.out.println(s);
// 2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
// b=it.hasNext();
// System.out.println(b);//true
// // 3、使用Iterator接口中的方法next取出集合中的下一个元素
// s=it.next();
// System.out.println(s);
// 2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
// b=it.hasNext();
// System.out.println(b);//true
// // 3、使用Iterator接口中的方法next取出集合中的下一个元素
// s=it.next();
// System.out.println(s);
//
// b=it.hasNext();
System.out.println(b);没有元素,返回false
// 3、使用Iterator接口中的方法next取出集合中的下一个元素
s=it.next();没有元素,在取出元素会抛出NoSuchElementException没有元素异常
System.out.println(s);
}
}
Iterator(迭代器)实现原理
这里我们来看看Java里AbstractList实现Iterator的源代码:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { // List接口实现了Collection<E>, Iterable<E>
protected AbstractList() {
}
public Iterator<E> iterator() {
return new Itr(); // 这里返回一个迭代器 }
private class Itr implements Iterator<E> { // 内部类Itr实现迭代器
int cursor = 0;
int lastRet = -1;
int expectedModCount = modCount;
public boolean hasNext() { // 实现hasNext方法
return cursor != size();
}
public E next() { // 实现next方法
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() { // 实现remove方法
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}
可以看到,实现next()是通过get(cursor),然后cursor++,通过这样实现遍历。
这部分代码不难看懂,唯一难懂的是remove操作里涉及到的expectedModCount = modCount;
在网上查到说这是集合迭代中的一种“快速失败”机制,这种机制提供迭代过程中集合的安全性。
从源代码里可以看到增删操作都会使modCount++,通过和expectedModCount的对比,迭代器可以快速的知道迭代过程中是否存在list.add()类似的操作,存在的话快速失败!
在第一个例子基础上添加一条语句:
import java.util.*;
public class Muster {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
Iterator it = list.iterator();
while(it.hasNext()){
String str = (String) it.next();
System.out.println(str);
list.add("s"); //添加一个add方法
}
}
}
运行结果:
a
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at com.hasse.Muster.main(Muster.java:11)
这就会抛出一个下面的异常,迭代终止。
增强for循环
增强for循环的作用: 简化迭代器的书写格式。(注意:增强for循环的底层还是使用了迭代器遍历。)
增强for循环的适用范围: 如果是实现了Iterable接口的对象或者是数组对象都可以使用增强for循环。
增强for循环的缺点:增强for循环和iterator遍历的效果是一样的,也就说增强for循环的内部也就是调用iteratoer实现的,但是增强for循环有些缺点,例如不能在增强循环里动态的删除集合内容、不能获取下标等。
for(数据类型 变量名 :遍历的目标){
//数据类型 变量名:声明一个变量用来接收遍历目标遍历后的元素
}
int[] arr = {5,11,2,4,9,18};
普通for循环的遍历方式
for(int i = 0 ; i<arr.length ; i++){
System.out.println("元素:"+ arr[i]);
}
//使用增强for循环实现
for(int item :arr){
System.out.println("元素:"+ item);
}
HashSet<String> set = new HashSet<String>();
//添加元素
set.add("张狗蛋");
set.add("张全蛋");
set.add("张傻蛋");
//使用迭代器遍历Set的集合.
Iterator<String> it = set.iterator();
while(it.hasNext()){
String temp = it.next();
System.out.println("元素:"+ temp);
it.remove();
}
//使用增强for循环解决
for(String item : set){
System.out.println("元素:"+ item);
}
注意: Map集合没有实现Iterable接口,所以map集合不能直接使用增强for循环,如果需要使用增强for循环需要借助于Collection的集合。
HashMap<String, String> map = new HashMap<String, String>();
map.put("01","甲");
map.put("02","乙");
map.put("03","丙");
map.put("04","丁");
Set<Map.Entry<String, String>> entrys = map.entrySet();
for(Map.Entry<String, String> entry :entrys){
System.out.println("键:"+ entry.getKey()+" 值:"+ entry.getValue());
}
标签:直接 toe lock asn add turn string except 网上
原文地址:https://blog.51cto.com/14954398/2558092