1. 集合框架图如下:

img

img

img

大致可以看出,Java 集合框架主要包含两种容器。一种是存储元素集合的 Collection,另一种是存储键值对的 Map。

总结:

  1. 集合主要分为两组(单列集合,双列集合)
  2. Collection 接口有两个重要的子接口 List 和 Set,他们实现的子类都是单列集合
  3. Map 接口实现的子类则是双列集合,存放K-V键值对

2. Collection 接口

2.1 Collection接口常用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
add
参数:array.add(Object o);
添加元素

remove
参数:array.remove(Object o);
删除指定元素

contains
参数:array.contains(Object o);
查找元素是否存在

size
获取元素个数

isEmpty
判断是否为空

clear
清空

addAll
参数:array.addAll(Collection c);
将另一个集合添加(添加多个元素)

containsAll
参数:array.containsAll(Collection c);
查找多个元素是否都存在

removeAll
参数:array.removeAll(Collection c);
删除多个元素

2.2 使用迭代器遍历 Collection

说明:

  1. Iterator 对象称为迭代器,主要用于遍历 Collection 集合中的元素
  2. 所有实现了 Collection 接口的集合类都有一个 iterator() 方法,用以返回一个实现了 iterator 接口的对象,即可以返回一个迭代器
  3. Iterator 仅用于集合的遍历,Iterator 本身并不存放对象
1
2
3
4
5
Iterator iterator = array.iterator();
while (iterator.hasNext()) {
String str = (String) iterator.next();
System.out.println(str);
}

2.3 List 接口

2.3.1 List 接口基本介绍

  1. List 集合类中的元素有序,并且可以重复
  2. List 集合中的每个元素都有其相应的顺序索引,即支持索引
  3. List 容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取相应元素

2.3.2 List 接口常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void add(int index, Object o);
在index位置插入o元素

boolean addAll(int index, Collection c);
从index位置插入c集合

Object get(int index);
获取index下标的元素

int indexOf(Object o);
返回o在集合中首次出现的位置

int lastIndexOf(Object o);
返回o在集合中最后一次出现的位置

Object remove(int index);
移出index下标位置的元素,并返回此元素

Object set(int index, Object e);
设置指定index位置的元素为e(替换)

List subList(int fromIndex, int toIndex);
返回从fromIndex下标到toIndex下标位置的子元素集合(前闭后开)

2.3.3 Vector、ArrayList 与 LinkedList 比较

  1. Vector 是线程安全的,但效率相对较低,所以在多线程时应使用 Vector
  2. ArrayList 和 Vector 都是以 Object 数组来存储的。在存储时如果数据个数超出了内部数组当前的长度,Vector 会自动增长为原数组大小的一倍,而 ArrayList 是50%,所以在存放大量数据时应使用 Vector 更有优势
  3. ArrayList 是基于动态数组来实现,而 LinkedList 是基于链表来实现。所以当需要大量随机访问元素时,ArrayList 是首选,而当需要大量的插入或删除元素时,LinkedList 是首选。(类比数组与链表)

2.4 Set接口

Set 接口实现了 Collection 接口,所以 Collection 的方法 Set 接口的实现类也能用

2.5 List 接口与 Set 接口对比

  1. Set 接口存储的数据是无序的,并且不能重复。而 List 接口实例存储的是有序的,可以重复的元素
  2. Set 检索效率较低,但是插入和删除效率高(因为插入和删除不会引起其他元素的位置的改变(内部实现其实还是哈希表与红黑树 HashSet、TreeSet))
  3. List 查找效率高,但是插入和删除效率较低(因为会引起其他元素位置的改变)

3. Map 接口

3.1 说明

Map 接口的常用实现类:HashMap、HashTable 和 Properties

3.1.1 HashMap 说明

  1. HashMap 是 Map 接口使用频率最高的实现类
  2. HashMap 是以 Key-Value 键值对的方式来存放数据
  3. Key 不能重复,但是 Value 可以重复
  4. 允许使用 null 键和 null 值
  5. 如果添加相同的 Key,则会覆盖原来的 Key-Value,相当于是修改(Key 不会替换,Value 会替换)
  6. 元素是无序的,底层是以哈希表的方式来存储的
  7. HashMap 没有实现同步,因此是线程不安全的

3.1.2 HashTable 说明

  1. 存放的元素是键值对
  2. HashTable 的键和值都不能为 null,否则抛出 NullPointerException
  3. HashTable 是线程安全的,而 HashMap 是线程不安全的

3.2 Map 常用操作

3.2.1 增删改查等操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Map map = new HashMap();

//1. put:添加
map.put("高一", "马");
map.put("高二", "朱");
map.put("高三", "张");
System.out.println(map);

//2. remove:根据键删除映射关系
map.remove("高一");
System.out.println(map);

//3. get:根据键获取值
System.out.println(map.get("高二"));

//4. size:获取元素个数
System.out.println(map.size());

//5. isEmpty:判断个数是否为0
System.out.println(map.isEmpty());

//6. containsKey:查找键是否存在
System.out.println(map.containsKey("高三"));

//7. 查找值是否存在
System.out.println(map.containsValue("张"));

//8. clear:清除
map.clear();
System.out.println(map);

3.2.2 遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//注:x.1 都是使用for-each,x.2 都是使用迭代器
//=======第一种遍历方式,先取出所有的键,再根据键获取值(keySet)=========
Set keyset = map.keySet();

System.out.println("========第1.1种方式========");
for (Object key : keyset) {
System.out.println(key + "-" + map.get(key));
}

System.out.println("========第1.2种方式========");
Iterator iterator = keyset.iterator();
while (iterator.hasNext()) {
Object key = iterator.next();
System.out.println(key + "-" + map.get(key));
}


//=======第二种遍历方式,只遍历值(用的不多)=========
System.out.println("========第2.1种方式========");
Collection values = map.values();
for (Object value : values) {
System.out.println(value);
}

System.out.println("=========第2.2种方式========");
Iterator iterator1 = values.iterator();
while (iterator1.hasNext()) {
System.out.println(iterator1.next());
}


//=======第三种遍历方式,通过遍历entrySet,然后转为Map.Entry,调用get========
System.out.println("==========第3.1种方式=======");
Set entrySet = map.entrySet();
for(Object entry:entrySet) {
Map.Entry m = (Map.Entry) entry;
System.out.println(m.getKey() + "-" + m.getValue());
}

System.out.println("==========第3.2种方式========");
Iterator iterator2 = entrySet.iterator();
while (iterator2.hasNext()) {
Map.Entry m1 = (Map.Entry) iterator2.next();
System.out.println(m1.getKey() + "-" + m1.getValue());
}

4. 开发中如何选择集合实现类

分析如下:

  1. 先判断存储的类型(一组对象或一组键值对)
  2. 一组对象:Collection 接口
    • 允许重复:List
      • 增删多:LinkedList(底层维护了一个双向链表)
      • 改查多:ArrayList(底层维护了一个 Object 类型的可变数组)
    • 不允许重复:Set
      • 无序:HashSet(底层是 HashMap,维护了一个哈希表)
      • 排序:TreeSet
      • 插入和取出顺序一致:LinkedHashSet(底层维护了数组+双向链表)
  3. 一组键值对:Map 接口
    • 键无序:HashMap(底层是哈希表 jdk7:数组+链表 jdk8:数组+链表+红黑树)
    • 键排序:TreeMap
    • 键插入和取出顺序一致:LinkedHashMap
    • 读取文件:Properties

5. Collections 工具类

5.1 工具类介绍

  1. Collections 是一个用来操作 Set、List 和 Map 等集合的工具类
  2. Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作

5.2 排序操作(均为static方法)

  1. reverse(List); 将List元素反转
  2. shuffle(List); 对List集合元素进行随机排序
  3. sort(List); 根据元素的自然顺序对指定List集合元素按升序排序
  4. sort(List, Comparator); 根据指定的排序方式对List排序
  5. swap(List, int i, int j); 将List集合中下标为 i 的元素与下标为 j 的元素进行交换

5.3 查找、替换操作

  1. Object max(Collection); 根据元素的自然顺序(字典序),返回最大元素
  2. Object max(Collection, Comparator); 根据指定顺序(如长度最大等)返回最大元素
    • 如:返回长度最大
    • Object maxObject = Collections.max(list, new Comparator() {
    • ​ @Override
    • ​ public int compare(Object o1, Object o2) {
    • ​ return ((String) o1).length() - ((String) o2).length();
    • ​ }
    • })
  3. Object min(Collection);
  4. Object min(Collection, Comparator);
  5. int frequency(Collection, Object); 返回出现次数最多的元素
  6. void copy(List dest, List src); 将src的内容复制到dest
  7. boolean replaceAll(List list, Object oldVal, Object newVal); 使用新值替换所有旧值

5.4 其他操作

创建一个线程安全的集合:

List synchronizedList(List list);

1
private static List<Connection> sqlList = Collections.synchronizedList(new ArrayList<>());