Java 集合类 3-深入浅出了解Collection的输出方式

 Collection接口的子类由于覆写了toString()方法,所以直接打印就可以进行内容的输出,但是,这并不是它们的标准输出方式。JDK提供了四中输出集合的方式,分别是:

  • Iterator
  • ListIterator
  • Enumeration
  • foreach

1. Iterator迭代器输出

 在JDK1.5之前,Collection接口中定义有iterator()方法,通过此方法可以取得Iterator接口的实例化对象。通过该实例化对象进行迭代器输出。

 而在JDK1.5之后,Collection接口继承Iterable接口,iterator()方法是该接口中的方法,该方法实质上还是返回一个Iterator接口的实例化对象,只是继承结构发生了改变,如下:

// 继承 Iterable 接口
public interface Collection<E> extends Iterable<E>

// 接口中还有其他的方法
public interface Iterable<T> {
    // 返回一个Iterator对象的实例
    Iterator<T> iterator();
}

 因为List接口和Set接口继承与Collection接口,所以它俩的子类也有这个方法。

 Iterator也是一个接口,在不同的类中,会自己实现接口中的方法。

 接口中主要方法如下:

public interface Iterator<E> {
    // 是否存在下一个元素
    boolean hasNext();
    // 取得下一个元素
    E next();
    // 删除当前元素
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
}

 注意:这里的”下一个元素”是以没有得到元素的时刻为时间参考点,实际上的意思就是获取当前元素。比较绕,大家一定要理解。

 使用如下:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        // Iterator()迭代输出,适用于Collection所有实现类
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(5);
        list.add(7);
        // 实例化iterator对象
        Iterator<Integer> iterator = list.iterator();
        // iterator使用格式,先判断是否存在元素,再获取该元素
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

运行结果:

运行结果

 关于迭代器还有一点要讲。在迭代器遍历集合的过程中,绝对不能对集合元素进行改变,否则会抛出 ConcurrentModificationException 异常。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test {
    public static void main(String[] args) {

        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(5);
        list.add(7);
        // 实例化iterator对象
        Iterator<Integer> iterator = list.iterator();
        // iterator使用格式
        while(iterator.hasNext()) {
            int remove = iterator.next();
            // 使用ArrayList的remove()方法
            list.remove(remove);
        }
    }
}

抛出异常:

异常

 Collection接口实现类的remove,add等操作会改变modCount(版本号,了解即可)。

 在iterator遍历期间,如果发现modCount与开始遍历时不一样,就会抛出 ConcurrentModificationException异常。

 而Iterator接口提供的remove不会修改modCount,所以非要修改的话,可以使用这个方法。

2. ListIterator双向迭代器

 Iterator迭代器只能从前向后将内容输出,而List接口扩充的ListIterator却可以从前向后,也可以从后向前。

// 取得ListIterator对象
public ListIterator listIterator();

 双向迭代器使用方法和迭代器一致,也是一个接口,其中的方法如下:

public interface ListIterator<E> extends Iterator<E> {

    // 是否含有下一个元素
    boolean hasNext();

    // 取得下一个元素
    E next();

    // 是否含有上一个元素
    boolean hasPrevious();

    // 取得上一个元素
    E previous();
}

 看下面的例子:

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Test {
    public static void main(String[] args) {

        // 双向迭代器ListIterator
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(5);
        list.add(7);
        // 实例化ListIterator对象
        ListIterator<Integer> listIterator = list.listIterator();
        // 从前到后输出
        System.out.println("从前向后依次输出:");
        while(listIterator.hasNext()) {
            System.out.println(listIterator.next());
        }
        // 从后向前输出
        System.out.println("从后向前依次输出:");
        while(listIterator.hasPrevious()) {
            System.out.println(listIterator.previous());
        }
    }
}

运行结果:

运行结果

 如果要想实现由后向前的输出,那么应该首先进行从前向后的输出,否则无法实现双向。

3. Enumeration枚举输出

 枚举输出是Vector子类所独有的,其它的子类都没有这种输出形式。Enumeration最早的设计就是为Vector服务的,在Vector类中提供有一个取得Enumeration接口对象的方法:

public Enumeration elements()

 Enumeration接口主要方法如下:

// 判断是否有下一个元素
public boolean hasMoreElements();

// 取得元素
public E nextElement();

 使用如下:

import java.util.Enumeration;
import java.util.Vector;

public class Test {
    public static void main(String[] args) {

        // Enumeration枚举输出
        Vector<Integer> vector = new Vector<>();
        vector.add(1);
        vector.add(3);
        vector.add(5);
        vector.add(7);
        // 获取Enumeration对象
        Enumeration<Integer> enumeration = vector.elements();
        while(enumeration.hasMoreElements()) {
            System.out.println(enumeration.nextElement());
        }
    }
}

运行结果:

运行结果

4. foreach输出

 从JDK1.5开始foreach可以输出数组(包含List),实际上除了数组之外也可以输出集合(Set)。

 使用如下:

import java.util.HashSet;
import java.util.Set;

public class Test {
    public static void main(String[] args) {

        // foreach输出,适用于Collection所有实现类
        Set<Integer> set = new HashSet<>();
        set.add(1);
        set.add(3);
        set.add(5);
        set.add(7);
        for(Integer tmp : set) {
            System.out.println(tmp);
        }
    }
}

运行结果:

运行结果

 这就是Collection的四种输出格式,推荐大家使用迭代器进行输出,因为该方法效率高,安全性好。

猜你喜欢

转载自blog.csdn.net/weixin_40739833/article/details/80533059