05Java的迭代器Iterator&工具类Collections

迭代器Iterator

迭代器Iterator是JDK提供的一种访问Collection接口(Set,List,Map)的工具,下面我们看Iterator接口的源码:

public interface Iterator<E> {
    
    
    /**
     * Returns {@code true} if the iteration has more elements.
     * (In other words, returns {@code true} if {@link #next} would
     * return an element rather than throwing an exception.)
     *
     * @return {@code true} if the iteration has more elements
     */
    boolean hasNext();

    /**
     * Returns the next element in the iteration.
     *
     * @return the next element in the iteration
     * @throws NoSuchElementException if the iteration has no more elements
     */
    E next();
    ......
}

其中 boolean hasNext(); 方法就是判断有没有下一个数据对象, E next(); 是一个指针,每遍历一次都指向当前数据对象。

其实,Collection接口的底层早已实现了Iterator接口,用List和Arraylist举例:

首先进入List接口源码,看见list继承了Collection接口:

public interface List<E> extends Collection<E> {
    
    }

进入Collection接口源码,看到Collection接口继承了Iterable接口:

public interface Collection<E> extends Iterable<E> {
    
    }

进入Iterable接口源码,看见Iterable接口里面定义了一个Iterator对象iterator,获得迭代器对象

public interface Iterable<T> {
    
    
    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    Iterator<T> iterator();
    ......
}

捋一下思路:Collection接口继承Iterable接口,Iterable接口里面把Iterator类实例化获得迭代器Iterator对象和方法。

在这里插入图片描述

下面使用迭代器Iterator来遍历ArrayList容器:

package myinterator;

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

/**
 * 测试迭代器Iterator遍历ArrayList容器
 *
 * @author 发达的范
 * @date 2020/11/19 19:45
 */
public class TestIterator {
    
    
    public static void main(String[] args) {
    
    
        testIterator();
    }

    public static void testIterator() {
    
    
        List<String> list = new ArrayList<>();
        list.add("qqq");
        list.add("www");
        list.add("eee");
        System.out.println(list);
        //这里在for循环里面定义了一个接口对象,就类似于int i=0;注意后面不需要加i++
        for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
    
    
            //iterator.next()既返回了当前的对象,也使游标向后移动并指向下一个数据对象
            String temp = iterator.next();
            System.out.println(temp);
        }
    }
}

运行结果:在这里插入图片描述

使用迭代器Iterator遍历Set容器也使类似:

public static void testIteratorSet() {
    
    
    Set<String> stringSet = new HashSet<>();
    stringSet.add("rrr");
    stringSet.add("ttt");
    stringSet.add("yyy");
    System.out.println(stringSet);
    for (Iterator<String> stringIterator = stringSet.iterator(); stringIterator.hasNext();) {
    
    
        String string = stringIterator.next();
        System.out.println(string);
    }
}

运行结果:在这里插入图片描述

使用迭代器Iterator遍历Map容器有所区别:

    public static void testIteratorMap01() {
    
    //遍历HashMap方法一
        Map<Integer, String> stringMap = new HashMap<>();
        stringMap.put(001,"uuu");
        stringMap.put(002,"iii");
        stringMap.put(003,"ooo");
        System.out.println(stringMap);
        Set<Map.Entry<Integer,String>> set=stringMap.entrySet();//Set获取stringMap中键值对的集合
        for (Iterator<Map.Entry<Integer, String>> iterator = set.iterator(); iterator.hasNext();) {
    
    
            Map.Entry<Integer,String> temp=iterator.next();
            System.out.println(temp);
        }
        /*//另一种写法,获取迭代器的时候不加泛型,遍历数据的时候强制转型
        for (Iterator iterator = set.iterator(); iterator.hasNext();) {
            Map.Entry<Integer,String> temp=(Map.Entry<Integer, String>) iterator.next();
            System.out.println(temp);
        }*/

        Set<Map.Entry<Integer, String>> set1 = stringMap.entrySet();//借助Set接口,把所有的键值对放入Set集合中
        //Set集合中有Iterator方法,获取所有键值对的迭代器
        Iterator<Map.Entry<Integer, String>> iterator = set1.iterator();
        while (iterator.hasNext()) {
    
    
            Map.Entry<Integer, String> temp = iterator.next();
            System.out.println(temp);
        }
    }

运行结果:在这里插入图片描述


    public static void testIteratorMap() {
    
    //遍历HashMap方法二
        Map<Integer, String> stringMap = new HashMap<>();
        stringMap.put(001,"ppp");
        stringMap.put(002,"aaa");
        stringMap.put(003,"sss");
        System.out.println(stringMap);
        Set<Integer> set = stringMap.keySet();//获得键的集合存在Set中
        for (Iterator<Integer> integerIterator = set.iterator(); integerIterator.hasNext(); ) {
    
    
            Integer key = integerIterator.next();
            System.out.println(key+"--"+stringMap.get(key));
        }
        Set<Integer> set1 = stringMap.keySet();
        Iterator<Integer> iterator = set1.iterator();//Set集合中有Iterator方法,获取所有键的迭代器
        while (iterator.hasNext()) {
    
    
            Integer key = iterator.next();
            System.out.println(key+"--"+stringMap.get(key));
        }
    }

运行结果:在这里插入图片描述

注:

Set、List接口中有迭代器,map接口中没有迭代器,那么该怎么遍历?

  1. Set< K >keySet():获取到所有的键,存储到一个Set集合中,并返回该集合,因为Set有迭代器,每次迭代出来的是一个键,再根据键来得到值

  2. Set<Map.Entry<K,V>>entrySet():获取到所有的键值对形成的映射关系,存到一个Set集合中,再迭代这个集合每次迭代出来的是一个映射关系,从这个映射关系中既可以得到键,也可以得到值这种映射关系是Map.Entry<K,V>类型的。

  • Entry是定义在Map中的一个静态成员,是一个接口
  • Entry为什么定义在Map里面?
    有了集合,有了集合中的键值对,才会存在映射关系,所以映射关系是对集合内部的事物描述所以定义在Map的内部

补充一些遍历容器的旧知识:

List<String> list = new ArrayList<>();
list.add("qqq");
list.add("aaa");
System.out.println(list);
for (String temp : list) {
    
    
    System.out.println(temp);
}
Set<String> set = new HashSet<>();
set.add("ddd");
set.add("nnn");
System.out.println(set);
for (String temp : set) {
    
    
    System.out.println(temp);
}

运行结果:在这里插入图片描述


工具类Collections

注意:这里的工具类Collections和Collection接口是完全不同的东西!

package mycollections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 测试Collections常用工具类的使用
 *
 * @author 发达的范
 * @date 2020/11/20 21:31
 */
public class TestCollections {
    
    
    public static void main(String[] args) {
    
    
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
    
    
            list.add("HUFL" + i);
        }
        System.out.println(list);
        Collections.shuffle(list);//随机打乱这个容器里对象的顺序
        System.out.println(list);
        Collections.reverse(list);//全部反转容器里的对象
        System.out.println(list);
        Collections.sort(list);//升序排列
        System.out.println(list);
        System.out.println(Collections.binarySearch(list,"HUFL6"));//二分查找法查找指定对象
        Collections.fill(list, "IEEE");//用指定对象填充指定容器
        System.out.println(list);
    }
}

运行结果:在这里插入图片描述

使用Map+List存储表格数据

表格如下:

ID Name Wages Register date
唐三藏 1 10000 1234
孙悟空 2 20000 1235
猪八戒 3 30000 1236

思路:使用一个Map对象存储一行数据,然后使用List存储这些Map对象

package mycollection;

import java.util.*;

/**使用容器存储表格数据
 *
 * @author 发达的范
 * @date 2020/11/20 22:12
 */
public class TestStoreData {
    
    
    public static void main(String[] args) {
    
    
        Map<String, Object> row1 = new HashMap<>();
        row1.put("ID", 001);
        row1.put("Name", "唐三藏");
        row1.put("Wages", 10000);
        row1.put("Register date", 1234);

        Map<String, Object> row2 = new HashMap<>();
        row2.put("ID", 002);
        row2.put("Name", "孙悟空");
        row2.put("Wages", 20000);
        row2.put("Register date", 1235);

        Map<String, Object> row3 = new HashMap<>();
        row3.put("ID", 003);
        row3.put("Name", "猪八戒");
        row3.put("Wages", 30000);
        row3.put("Register date", 1236);

        List<Map<String, Object>> list = new ArrayList<>();
        list.add(row1);
        list.add(row2);
        list.add(row3);
        Iterator<Map<String, Object>> iterator = list.iterator();
        while (iterator.hasNext()) {
    
    
            System.out.println(iterator.next());
        }

        for (Iterator<Map<String, Object>> iterator1 = list.iterator(); iterator1.hasNext(); ) {
    
    
            Map<String, Object> temp = iterator1.next();
//            System.out.println(temp);//使用这句输出结果和上一种遍历方式的输出相同
            System.out.print("Name:"+temp.get("Name")+" ");
            System.out.print("ID:"+temp.get("ID")+" ");
            System.out.print("Wages:"+temp.get("Wages")+" ");
            System.out.println("Register date:"+temp.get("Register date")+" ");
        }
    }
}

运行结果:在这里插入图片描述

两种遍历容器的方法本质上是相同的,只是第二种方式我是按照我指定的顺序显示数据。

当然,还可以使用其他容器结合来存储这个表格。

猜你喜欢

转载自blog.csdn.net/fada_is_in_the_way/article/details/109868704