iterator 迭代集合元素
Iterator it=set1.iterator();
//set1.add("1");
while (it.hasNext()){
System.out.println(it.next());
}
如果set1.add(“1”); 在调用迭代器后再新增一个元素,程序将报错
在定义一个集合时使用泛型
会使得集合内元素形式单一,后续处理不需要很多向下转型
//在建立对象的 时候使用 泛型,将使得 集合内元素单一,后续处理不需要大量的向下转型
//而在大多数业务中 集合的元素类型统一,所以这种泛型机制 在迭代中获得认可
//如果Interator 不加泛型的话 它的next默认返回是一个Object 类
如何只迭代出Object中的int 或String
Iterator it1=list1.iterator();
while (it1.hasNext()){
Object x=it1.next();
if(x instanceof Integer){
System.out.println(x);
}
if(x instanceof String){
System.out.println(x);
}
}
不加泛型机制 ,如何在跌带中返回自定义类
进行强制转化
List list1=new LinkedList();
for (int i = 0; i <5 ; i++) {
list1.add(i);
}
list1.add("asDASF");
list1.add("asdgsg");
list1.add("asd");
list1.add(new Student());
list1.add(new School());
list1.add(new Teacher());
Iterator it1=list1.iterator();
while (it1.hasNext()){
/*School s=it1.next();
s.shangke();*/
//System.out.println(it1.next());
Object x=it1.next();
if(x instanceof Integer){
System.out.println("输出int类型"+x);
}else if(x instanceof String){
System.out.println("输出String 类型"+x);
}else if((x instanceof School)){
School x1=(School)x;
x1.shangke();
}
}
}
}
class School{
public void shangke(){
System.out.println("学校开门");
}
public School() {
}
}
class Student extends School{
public void shangke(){
System.out.println("学生上课");
}
public Student() {
}
}
class Teacher extends School{
public void shangke(){
System.out.println("老师上课");
}
加了泛型机制后,集合元素变单一
list1.add(new Student());
list1.add(new School());
list1.add(new Teacher());
Iterator<School> it1=list1.iterator();
while (it1.hasNext()){
School s=it1.next();
s.shangke();
}
上面只适合调用School有的方法,如果需要进行调用其他子类才有方法,则需要向下转型。
关于迭代器和集合里的remove方法
在每次Iterator中 的每次循环next每次只能调用一次 否之报NoSuchElementException异常 即不确定下一个元素是否在
相对应如果直接使用集合的remove 仅仅可以使用一次,否之会报ConcurrentModificationException
(后续学了多线程,要理解这个异常,即待解决)
原因可参考
我的理解是在使用迭代器的时候,就像分身,在进行迭代的过程中,我只能对分身进行修改(即用迭代器的方法对对象进行修改),分身在外面干啥,都可以认定真身干了。
但是如果在造出迭代器之后,即产生了分身后,我真身一旦动了,就会干扰分身,会出现问题。
所以在迭代器内 用集合的增删,都会出现ConcurrentModificationException异常。
package com.hdu.collectiontest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class CollectionIterator {
public static void main(String[] args) {
Collection c=new ArrayList();
c.add("ad");
//c.add("zms");
c.add(123);
c.add(256);
c.add("ASDFAF");
c.add("zms");
c.add(111);
c.add(666);
c.add("a");
c.add("b");
c.add("ccc");
c.add(new Object());
System.out.println("第一次Iterator输出");
Iterator it=c.iterator();
while (it.hasNext()){
System.out.println("111"+it.next());//在每次Iterator中 的每次循环next每次只能调用一次 否之报NoSuchElementException异常 即不确定下一个元素是否在
//System.out.println("222"+it.next());
}
System.out.println("使用Iterator.remove和集合.remove输出");
Iterator it1=c.iterator();
while (it1.hasNext()){
Object obj=it1.next();
System.out.println(obj);
/* if(obj=="zms"){// 可以多次使用,,, 即在迭代器删除过程中,都可以使用迭代器的remove进行删除
it1.remove();
}
if(obj=="ad"){//
it1.remove();
}
if(obj=="ccc"){//
it1.remove();
}*/
//it1.remove();//这样的话 每次都删除
if(obj=="ccc"){//相对应如果直接使用集合的remove 仅仅可以使用一次
c.remove("ccc");
}
/*if(obj=="ad"){//直接使用集合的remove 使用两次迭代器删除之后 ConcurrentModificationException
c.remove("ad");
}*/
}
System.out.println("在使用迭代器之后 for循环输出");
Iterator it2=c.iterator();
while (it2.hasNext()){
System.out.println(it2.next());
}
System.out.println("在使用迭代器的remove之后 for循环输出");
for (Object x:c
) {
System.out.println(x);
}
}
}
Iterator和Iterable
Iterator接口的实现类iterator;二者主要有三个方法:hasnext(),next(),remove();
其中Collection继承了Iterable,意为着Collection所有的实现类都可以实现Iterable的方法,
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
}
那么其作用是什么呢?
我们在用iterator遍历的时候,是单向遍历,但实际上对于LinkedList是双向链表,单向遍历可能不能满足我们平常需求,所以在LinkedList内部就有private class ListItr implements ListIterator<E>
和private class DescendingIterator implements Iterator<E>
实现双向遍历和逆序遍历。但实际上也是调用了iterator方法,来实现不同的遍历过程。
因此Iterable是能够让其他集合实现一个不同的遍历方式,使得遍历方法更加灵活