集合是用来存放对象的容器。所有集合类都位于java.util包下,但支持多线程的集合类位于java.util.concurrent包下。

1、集合的概念

关于集合的定义,有以下三点注意:

  • 集合只能存放对象。基本数据类型会进行自动装箱转化为对应的引用类型;
  • 集合存放的都是对象的引用,而非对象本身。对象本身还是放在堆内存中;
  • 集合可以存放多种类型,不限数量的数据类型。

集合与数组的区别:

  • 数组的长度不可变化,且不能存放具有映射关系的数据(k-v);集合用来保存数量不确定的数据,且可以保存具有映射关系的数据;
  • 数组既可以存放基本类型的数据,又可以存放对象;集合只能存放对象。

Java将一些具有相似属性和功能的数据结构抽象为一组公共的接口,Java的集合框架就是围绕这些标准接口进行设计的,你可以直接使用这些接口的标准实现,也可以通过这些接口实现自己的集合类。

2、Java集合框架

Java集合框架是由两个根接口:Collection接口和Map接口派生而来的。Collection接口派生出了三个子接口:List、Set、Queue,List接口有两个比较常用的实现类:ArrayList和LinkedList,Set接口有两个比较常用的实现类:HashSet和TreeSet,Queue的实现类也有LinkedList;Map接口有两个比较常用的实现类:HashMap和TreeMap,还有个不经常用的实现类:HashTable。注意的是Collection接口和Map接口也被抽象类AbstractList和AbstractMap实现,具体的实现类比如ArrayList在实现了List接口的同时也继承了AbstractList抽象类。
集合框架图如图所示,这里引用的是链接1中的图,注意图中忽略了抽象类AbstractList和AbstractMap。
集合类概述 - 图1

集合类概述 - 图2

3、迭代器Iterator

迭代器是用来遍历集合类的。上面讲的集合框架的两个根接口:Collection接口和Map接口,其中Collection接口又继承了更顶层的Iterable接口,Iterable接口里又封装了 Iterator 接口,源码如下:

  1. public interface Iterable<T> {
  2. /**
  3. * Returns an iterator over elements of type {@code T}.
  4. *
  5. * @return an Iterator.
  6. */
  7. Iterator<T> iterator();
  8. ...
  9. }

Iterator 接口里包含了三个重要方法:

  1. public interface Iterator<E> {
  2. // 若被迭代的集合里还有元素没有被遍历,返回true.
  3. boolean hasNext();
  4. // 返回集合的下一个元素.
  5. E next();
  6. // 删除集合上一次next()方法返回的元素
  7. default void remove() {
  8. throw new UnsupportedOperationException("remove");
  9. }
  10. }

因此只要是实现了Collection接口的集合类,都可以调用Iterator迭代器遍历集合类,通用方法如下:

Iterator iter = l.iterator();
while(iter.hasNext()){
       System.out.println(iter.next());
}

其中l为实现了Collection接口的集合类。

注意:Map接口并没有继承Iterable接口,因此实现了Map接口的类不能直接通过map.iterator()得到迭代器,需要将Map类通过map.entrySet()转化为Set集合类(实现了Collection接口),再通过set.iterator()使用迭代器。

3.1 用迭代器遍历Collection接口的实现类

以ArrayList为例,代码如下:

public class Demo {
    public static void main(String[] args) {
        List<Integer> myList = new ArrayList<Integer>();
        for (int i = 0; i < 10; ++i)
        {
            myList.add(i);
        }
        Iterator iterator = myList.iterator();
        while (iterator.hasNext())
        {
            System.out.println(iterator.next());
        }
    }
}

3.2 用迭代器遍历Map接口的实现类

以HashMap为例,代码如下:

public class Demo {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("Jerry", 1);
        map.put("Cissie", 2);
        // 通过entrySet()方法将map中的entry(k-v对)放入到set
        Set<Map.Entry<String, Integer>> set = map.entrySet();
        // 获得set的迭代器遍历set,相当于间接地遍历了map
        Iterator iterator = set.iterator();
        while (iterator.hasNext())
        {
            System.out.println(iterator.next());
        }
    }
}

参考

https://zhuanlan.zhihu.com/p/86578960
https://www.cnblogs.com/lixiansheng/p/11348050.html