上一课学习了数组,那么这一节来学习一下集合和Map。
由一个或多个确定的元素所构成的整体被称为集合,集合具有无序性,但是Java内的集合多种多样,下面我们一起来学习Java中常用的集合。
学习目标
- 掌握ArrayList、HashSet的使用
 - 掌握HashMap的使用
 
集合的好处
我们知道,数组有一个固定的长度,一旦固定下来,就不可更改了。
而集合的出现,正好解决了这个问题,而且Java的集合类还提供了很多实用的方法,方便我们对一个数组进行各种操作,下面我们一起先来了解一下Collection类。
Collection类
观察下面一幅图,箭头指向的是它们的父类,比如右下叫的ArrayList,它的父类是AbstractList,而AbstractList的父类是AbstractCollection。
最终,所有类的父类都指向了Collection,因此,它是Java集合类的顶级类。

在Collection下有Set、List、Queue三个子类,本期先学习Set和List,Queue日后再谈。
Collection类的常用方法
- boolean add(E e) 向集合添加元素e,若指定集合元素改变了则返回true
 - boolean addAll(Collection c) 把集合C中的元素全部添加到集合中,若指定集合元素改变返回true
 - void clear() 清空所有集合元素
 - boolean contains(Object o) 判断指定集合是否包含对象o
 - boolean containsAll(Collection c) 判断指定集合是否包含集合c的所有元素
 - boolean isEmpty() 判断指定集合的元素size是否为0
 - boolean remove(Object o) 删除集合中的元素对象o,若集合有多个o元素,则只会删除第一个元素
 - boolean removeAll(Collection c) 删除指定集合包含集合c的元素
 - boolean retainAll(Collection c) 从指定集合中保留包含集合c的元素,其他元素则删除
 - int size() 集合的元素个数
 - T[] toArray(T[] a) 将集合转换为T类型的数组
 
这些方法我们会在下面的学习中逐个介绍,不管是List还是Set,它们也是最常用到的方法。
ArrayList
ArrayList是List的一种,还有另一种LinkedList,本期主要学习ArrayList的使用。
声明ArrayList
首先我们先声明一个变量:
List<String> arrayList = new ArrayList<>();
像上面这样,我们就声明了一个String类型的ArrayList。
概括出它的语法:List<数据类型> 变量名 = new ArrayList<>();
我们可以试着声明一个int类型的List:
List<Integer> arrayList = new ArrayList<>();
添加/获取/删除元素
添加元素很简单,用 变量名.add(元素) 即可。
public static void main(String[] args) {
    List<Integer> arrayList = new ArrayList<>();
    arrayList.add(233);
    arrayList.add(16);
}
像这样,我们就给这个List添加了两个元素。
等同于一个长度为2的一维数组,List的添加顺序是添加到最后。
也就是说,这个List的第一个元素是233,第二个元素是16,对应的下标分别是0和1。
我们来试着获取一个元素,仍然用上面的List举例,我们试着获取第二个元素16:
public static void main(String[] args) {
    List<Integer> arrayList = new ArrayList<>();
    arrayList.add(233);
    arrayList.add(16);
    System.out.println(arrayList.get(1));
}
输出的结果就是16,这里我们就用了get方法。
接着我们试着删除第一个元素,再获取第二个元素试试看。
public static void main(String[] args) {
    List<Integer> arrayList = new ArrayList<>();
    arrayList.add(233);
    arrayList.add(16);
    arrayList.remove(0); // 移除下标为0的元素 即第一个元素
}
现在我们再试着获取一下第二个元素16,注意现在这个List只有一个元素16,所以这个元素的下标要向前移动一位,也就是从1到0,因为233被移除后,它就是第一项。
public static void main(String[] args) {
    List<Integer> arrayList = new ArrayList<>();
    arrayList.add(233);
    arrayList.add(16);
    arrayList.remove(0);
    System.out.println(arrayList.get(0));
}
所以输出的结果就是16。
是否包含某个元素
若要检查集合中是否存在某一个元素,我们需要用到contains函数,它的返回值是布尔型。
public static void main(String[] args) {
    List<Integer> arrayList = new ArrayList<>();
    arrayList.add(233);
    arrayList.add(16);
    System.out.println("列表中是否存在233" + arrayList.contains(233));
}
// 运行结果
// 列表中是否存在233 > true
将某个集合添加到ArrayList
现在如果有两个ArrayList,分别为a和b,我们要把b的所有元素添加到a后面,也就是a的尾部与b的头部进行拼接,这时我们可以用addAll来实现。
这个操作并不会改变b的元素,可以认为是将b的元素复制一份加载了a后面。
public static void main(String[] args) {
    List<Integer> a = new ArrayList<>();
    a.add(1);
    a.add(3);
    a.add(5);
    
    List<Integer> b = new ArrayList<>();
    b.add(6);
    b.add(10);
    
    a.addAll(b);
}
这里两个List的元素分别由1、3、5和6、10。
当我们使用addAll后,b的所有元素就被添加到了a中,此时a的长度为5,下标最大就是4。
现在我们用get方法来获取一下下标为4的元素:
public static void main(String[] args) {
    List<Integer> a = new ArrayList<>();
    a.add(1);
    a.add(3);
    a.add(5);
    List<Integer> b = new ArrayList<>();
    b.add(6);
    b.add(10);
    a.addAll(b);
    System.out.println(a.get(4));
}
运行结果就是10。
获取集合长度
直接使用 集合变量.size(); 即可。
public static void main(String[] args) {
    List<Integer> a = new ArrayList<>();
    a.add(1);
    a.add(3);
    a.add(5);
    System.out.println("a集合的长度为 > " + a.size());
}
// 运行结果
// a集合的长度为 > 3
HashSet
Set不同于List,最大的特点就是无序性和不重复性,满足数学上的集合。
HashSet没有get方法,因为它是无序的。
因此我们使用add添加元素后,无法获取具体的某个元素,但我们可以用for循环来遍历它,这个方法我们将会在下一课学到。
那么有关于HashSet的各种方法,详见ArrayList的介绍。
HashMap
HashMap是Map的子类,Map不同于集合,它们的对比如下:
Collection中的元素是独立的,使用add将元素一个个添加进去。
Map中常用的集合为HashMap集合、LinkedHashMap集合,本期我们学习HashMap。
声明HashMap
和ArrayList一样,也需要用到一个<>来表示数据类型:
public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
}
这里的不同点就是,<>需要传入两个类,第一个是键的数据类型,第二个是值的数据类型。
可以看到,这里的Map是整数对应一个字符串。
Map的常用方法
- get(Object key) 通过键获取值
 - put(Object key, Object value) 将键值对添加到Map
 - remove(Object key) 移除某个键值对
 
下面我们来看看它们的用法:
public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(0, "这里是0对应的值");
    map.put(192, "这里是192");
}
像这样,我们就传入了两个键值对,接下来我们试着获取它们:
public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(0, "这里是0对应的值");
    map.put(192, "这里是192");
    System.out.println(map.get(192));
}
// 运行结果
// 
这里是192
而要移除一个键值对也很简单,使用remove即可:
public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    map.put(0, "这里是0对应的值");
    map.put(192, "这里是192");
    System.out.println(map.get(192));
    map.remove(192);
    System.out.println(map.get(192));
}
// 运行结果
// 这里是192
// null
观察发现,在移除192之后再尝试获取192对应的值,发现输出的是null空值,说明这个键值对已经被移除了。
课后练习
- 声明一个ArrayList和Map,自行练习增删查改。
 - 集合与Map的区别是什么?
 - 对于List和Map,你能想到哪些实际应用可以用它们实现?
 
			