Java_container

集合框架


集合框架可以分为:

  • Collection,主要由List、Set、Queue组成
    • list:有序、可重复的集合。如:ArrayList和LinkedList
    • Set:无序、不可重复的集合。如:HashSet和TreeSet
    • Queue:队列。如:ArrayDeque,PriorityQueue
  • Map,代表键值对集合。如:HashMap

List

存取有序,可以存重复元素,可以索引访问

ArrayList

增删查改:

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
import java.awt.*;  
import java.util.ArrayList;
import java.util.Arrays;

public class test{
public static void main(String[] args){
// 创建一个集合
ArrayList<String> list = new ArrayList<String>();
// 添加元素
list.add("hihihi");
list.add("oioioi");
list.add("goodgood");

// 遍历集合--for
System.out.println("第一次遍历");
for(int i=0;i<list.size();i++){
String s = list.get(i);
System.out.println(s);
}
System.out.println("第二次遍历");
// 遍历集合--for each
for(String s:list){
System.out.println(s);
}

// 删除元素--删除下标为i的元素 list.remove(i) list.remove(2);
System.out.println("删除元素后遍历");
for(String s:list){
System.out.println(s);
}

//修改元素
System.out.println("修改元素后遍历");
list.set(1,"pig");
for(String s:list){
System.out.println(s);
}
}
}

运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
第一次遍历
hihihi
oioioi
goodgood
第二次遍历
hihihi
oioioi
goodgood
删除元素后遍历
hihihi
oioioi
修改元素后遍历
hihihi
pig
  • ArrayList是由数组实现的,支持随机存取(可以通过下标存取)
  • 从尾部插入和删除效率高于从中间插入和删除。涉及数组元素的复制和移动
  • 如果内部数组容量不足会自动扩容,但是效率也会降低

创建ArrayList

我们通过创建对象的方法来创建就行了。
ArrayList<String> alist = new ArrayList<String>();
或
ArrayList<String> alist=new ArrayList<>();

  • 编译器会根据前面的进行智能推断,得到尖括号的类型。
  • 创建的时候会自动调用无参构造的方法,创建按一个空的数组
  • 但我们也可以在最开始就提供我们期望的ArrayList元素个数,防止不必要的扩容 List<String> alist = new ArrayList<>(20);

添加元素

这里使用到 add() 方法

  • 可以直接在队尾添加元素也可以在指定位置添加元素
1
2
list.add("hi");
list.add(0,"hj");//add(int index, E element)

更新元素

set(index,element);
该方法会先对指定的下标进行检查,看是否越界,然后替换新值并返回旧值

删除元素

1
2
alist.remove(1);
alist.remove("沉默王四");

可以删除指定下标位置上的元素,也可以删除指定值的元素

remove(Object o):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 删除列表中第一次出现的指定元素(如果存在)。
*
* @param o 要删除的元素
* @return 如果列表包含指定元素,则返回 true;否则返回 false
*/
public boolean remove(Object o) {
if (o == null) { // 如果要删除的元素是 null
for (int index = 0; index < size; index++) // 遍历列表
if (elementData[index] == null) { // 如果找到了 null 元素
fastRemove(index); // 调用 fastRemove 方法快速删除元素
return true; // 返回 true,表示成功删除元素
}
} else { // 如果要删除的元素不是 null
for (int index = 0; index < size; index++) // 遍历列表
if (o.equals(elementData[index])) { // 如果找到了要删除的元素
fastRemove(index); // 调用 fastRemove 方法快速删除元素
return true; // 返回 true,表示成功删除元素
}
}
return false; // 如果找不到要删除的元素,则返回 false
}

有相同元素时,只会删除第一个。

查找元素

如果要正序查找一个元素,可以使用 indexOf() 方法;如果要倒序查找一个元素,可以使用 lastIndexOf() 方法。

1
2
alist.indexOf("沉默王二");
alist.lastIndexOf("沉默王二");

LinkedList

增删查改和ArrayList没什么差别。差别在他们实现的底层逻辑。
顾名思义,这个列表是通过链表来实现的。

  • 在任意地方的插入和删除都一样方便,只需要修改前一个节点和后一个节点,而无需复制移动
  • 由双向链表实现的,支持顺序查找,不支持随机存取。
  • 占用的空间更大。

Vector和Stack

Vector 是线程安全的,像 get、set、add 这些方法都加了 synchronized 关键字,就导致执行效率会比较低

  • 如果不需要线程安全,建议使用 ArrayList 代替 Vector。

Stack 是 Vector 的一个子类,本质上也是由动态数组实现的,只不过还实现了先进后出的功能(在 get、set、add 方法的基础上追加了 pop「返回并移除栈顶的元素」、peek「只返回栈顶元素」等方法),所以叫栈。

Set

存取无序、不可存放重复元素,不可以用下标对元素进行操作。

HashSet

HashSet是由HashMap实现的,只不过值是由一个固定的Object对象填充,而键用于操作。

  • 很少用
  • HashSet 主要用于去重

LinkedHashSet

LinkedHashSet 虽然继承自 HashSet,其实是由 LinkedHashMap 实现的。

TreeSet

TreeSet 是一种基于红黑树实现的有序集合,它实现了 SortedSet 接口,可以自动对集合中的元素进行排序。按照键的自然顺序或指定的比较器顺序进行排序。

Queue

ArrayDqeue

基于数组实现的双端队列,为了满足可以同时在数组两端插入或删除元素的需求,数组必须是循环的,也就是说数组的任何一点都可以被看作是起点或者终点。

Map

Map 保存的是键值对,键要求保持唯一性,值可以重复。

HashMap

HashMap实现了Map接口(因为Map是一个接口,所以我们平时不能直接实例化Map,而是要实例化实现他的子类)

HashMap 的特点:

  • HashMap 中的键和值都可以为 null。如果键为 null,则将该键映射到哈希表的第一个位置。
  • 可以使用迭代器或者 forEach 方法遍历 HashMap 中的键值对。
  • HashMap 有一个初始容量和一个负载因子。初始容量是指哈希表的初始大小,负载因子是指哈希表在扩容之前可以存储的键值对数量与哈希表大小的比率。默认的初始容量是 16,负载因子是 0.75。

添加键值对:put(key,value)
获取指定键的值:get(key)
修改键对应的值:put(key,newvalue)
删除指定键的键值对:remove(key)

LinkedHashMap

HashMap是无序的,所以我们如果要一个有序的Map,就可以用到 LinkedHashMap.

  • LinkedHashMap 是 HashMap 的子类,它使用链表来记录插入/访问元素的顺序。

TreeMap

TreeMap 实现了 SortedMap 接口,可以自动将键按照自然顺序或指定的比较器顺序排序,并保证其元素的顺序。内部使用红黑树来实现键的排序和查找。