随笔都是学习笔记
随笔仅供参考,为避免笔记中可能出现的错误误导他人,请勿转载。

简介:

在之前对集合的输出使用的是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中的方法进行输出,但是使用这种方式输出也无妨。

 

 
posted on 2022-03-14 16:18  时间完全不够用啊  阅读(271)  评论(0编辑  收藏  举报