• List接口的实现类
    • ArrayList:动态数组实现,允许重复元素
    • LinkedList:双向链表实现,允许重复元素
  • Set接口的实现类
    • HashSet:基于哈希表实现,不允许重复元素
    • LinkedHashSet:基于哈希表和链表实现,不允许重复元素,保持插入顺序
    • TreeSet:基于红黑树实现,不允许重复元素,元素自动排序

Collection

Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的

collection方法

  • 把给定的对象添加到当前集合中

1. 如果我们向List系列集合中添加数据,那么方法永远会返回true,因为List系列是允许元素重复

2.如果我们向Set系列集合中添加数据,那么方法会根据是否存在而返回true或false,因为Set系列是不允许元素重复的

1
2
Collection<E> coll = new ArrayList<> ();
coll.add(e);
  • 清空集合中所有的元素
1
2
3
Collection<E> coll = new ArrayList<> ();
coll.add(e);
coll.clear();
  • 把给定的对象在当前集合中删除

1.这个方法会返回一个布尔类型的值,当要删除的元素不存在,就会返回false

2. 因为Collection里面定义的是List和Set共性的方法,所以不能通过索引进行删除,只能通过元素的对象进行删除

1
2
3
Collection<E> coll = new ArrayList<> ();
coll.add(e);
coll.remove(e);
  • 判断当前集合中是否包含给定的对象

在源码中contains方法是依赖equals方法进行判断是否存在,因此如果集合中存储的是自定义对象,在JavaBean中一定要重写equals方法

1
2
3
Collection<E> coll = new ArrayList<> ();
coll.add(e);
coll.contains(e);
  • 判断当前集合是否为空
1
2
Collection<E> coll = new ArrayList<> ();
coll.isEmpty();
  • 返回集合元素中个数/集合的长度
1
2
Collection<E> coll = new ArrayList<> ();
coll.size();

Collections

Collections是集合的工具类

  • 打乱集合中的元素
1
2
Collection<E> coll = new ArrayList<> ();
Collections.shuffle(coll);
  • 获取集合中的最大值
1
2
Collection<E> coll = new ArrayList<> ();
Collections.max(coll);
  • 批量添加元素
1
2
Collection<E> coll = new ArrayList<> ();
Collections.addAll(coll,"1","2","3"
  • 排序
1
2
3
Collection<E> coll = new ArrayList<> ();
//按照指定规则进行排序
Collections.sort(list, Comparator<T> c);
  • 以二分查找查找元素
1
2
Collection<E> coll = new ArrayList<> ();
Collections.binarySearch(coll, T key);
  • 拷贝集合中的元素
1
2
3
Collection<E> coll = new ArrayList<> ();
//将coll拷贝到target
Collections.copy(target, coll);
  • 交换集合指定位置的元素
1
2
Collection<E> coll = new ArrayList<> ();
Collections.swap(coll, 1, 2);

遍历方法

迭代器遍历

1.迭代器在遍历集合的时候不依赖索引

2. 迭代器遍历完毕,指针不会复位,如果还要进行遍历,则需要重新获取一个迭代器对象

3. 一个循环中只能使用一次next方法,不然可能会报NoSuchElementException错误

4. 迭代器在遍历的时候,不能用集合的方法进行增加和删除,但是可以用迭代器提供的remove方法进行删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Collection<String> collection = new ArrayList<>();
collection.add("aaa");
collection.add("bbb");
collection.add("ccc");
// 获取集合的迭代器对象,用于遍历集合中的所有元素
Iterator<String> iterator = collection.iterator();
//hasNext():判断当前位置是否有元素
while (iterator.hasNext()) {
//next():获取当前位置的元素,并将迭代器对象移向下一个位置
String element = iterator.next();
if ("bbb".equals(element)) {
//用迭代器提供的remove进行删除
iterator.remove();
}
System.out.println(element);
}

增强for遍历

增强for的底层就是迭代器,为了简化迭代器的代码而存在的

1
2
3
4
5
Collection<E> collection = new ArrayList<>();
for (E e : collection){
//这里的e相当于是定义了一个变量e,然后将collection的值赋给了e,所以当修改e的变量时,并不会修改原本的数据
System.out.println(e);
}

lambda表达式

lambda表达式允许以简洁的语法编写匿名内部类。Lambda表达式主要用于实现单个抽象方法的接口,这种接口被称为函数式接口(Functional Interface),这是一个只有一个抽象方法的接口。

1
2
3
4
5
6
7
8
9
10
Collection<E> collection = new Collection<> ();
//利用匿名内部类的形式
collection.forEach(new Consumer<E>(){
@Override
public void accept(E e) {
System.out.println(e);
}
});
//用lambda表达式简化
collection.forEach(e -> System.out.println(e));

List

List集合特有方法

  • 在集合的指定位置插入指定的元素
1
2
3
4
ArrayList<E> list = new ArrayList<> ();
list.add(e1);
//在集合的指定位置插入指定的元素
list.add(1,e1);
  • 删除指定索引处的元素,返回被删除的元素
1
2
3
4
ArrayList<E> list = new ArrayList<> ();
list.add(e);
//删除指定索引处的元素,返回被删除的元素
E res = list.remove(0);
1
2
3
4
5
6
7
8
9
10
11
ArrayList<Integer> list = new ArrayList<> ();
list.add(1);
list.add(2);
list.add(3);
list.add(1);
//此时删除的是索引1处的元素,而不是大小等于1的元素
//因为在调用方法的时候,如果方法出现了重载现象,会优先调用实参和形参类型一致的那个方法
//这里的1的是基本数据类型int,所以调用了删除索引处元素的remove方法
list.remove(1);
//如果要删除大小等于1的元素,可以参照如下
list.remove(Integer.valueOf(1));
  • 修改指定索引处的元素,返回被修改的元素
1
2
3
4
ArrayList<E> list = new ArrayList<> ();
list.add(e);
//修改指定索引处的元素,返回被修改的元素
E res = list.set(0,i);
  • 返回指定索引处的元素
1
2
3
4
ArrayList<E> list = new ArrayList<> ();
list.add(e);
//返回指定索引处的元素
E res = list.get(0);

遍历方法

  1. 迭代器遍历
  2. 增强for循环
  3. lambda表达式
  4. 普通for循环
  5. 列表迭代器(可以在遍历过程中添加,修改元素)

列表迭代器还可以反向遍历集合,用hasPrevious() 和 previous()

1
2
3
4
5
6
7
8
9
10
11
ArrayList<E> list = new ArrayList<> ();
ListIterator<E> it = list.listIterator();
while (it.hasNext()) {
E e = it.next();
if (i.equals(e)) {
//调用迭代器中的方法添加元素
it.add(i);
//调用迭代器中的方法修改元素
it.set(i);
}
}

ArrayList

ArrayList集合原理:

  1. 利用空参创建的集合,在底层创建一个默认长度为0的数组
  2. 添加第一个元素时,底层会创建一个新的长度为10的数组
  3. 当数组存满时,会扩容1.5倍
  4. 如果一次添加多个元素,1.5倍还放不下,则创建数组的长度和实际需要的长度一致

LinkedList

LinkedList的底层数据类型是双链表,因此有很多首尾操作的特有API

  • 在列表开头插入特定的元素public void addFirst(E e)

  • 将指定的元素追加到列表的末尾 public void addLast(E e)

  • 返回列表中的第一个元素 public E getFirst()

  • 返回列表中的最后一个元素 pubic E getLast()

  • 在列表中删除并返回第一个元素 public E removeFirst()

  • 在列表中删除并返回最后一个元素 public E removeLast()

Set

HashSet

哈希值:

  • 根据hashCode方法算出来的int类型的整数
  • 所有对象都有哈希值,默认使用的地址值进行计算
  • 一般来说,会重写hashCode方法,利用对象内部的属性值计算哈希值
  • 在小部分情况下,不同属性值或者不同地址值计算出来的哈希值可能一样(哈希碰撞)

HashSet底层原理:

  1. 创建一个默认长度16,默认加载因为0.75的数组,数组名为table
  2. 根据元素的哈希值跟数组的长度计算出应存入的位置
  3. 判断当前位置是否为null,如果是null直接存入
  4. 如果位置不为null,表示有元素,则调用equals方法比较属性值
  5. 一样:不存;不一样:存入数组,形成链表,新元素直接挂在老元素下面(JDK8以前新老元素位置相反)

LinkedHashSet

LinkedHashSet底层原理:底层数据结构依然是哈希表,只是每个元素又额外多了一个双链表的机制记录存储的顺序,因此有序(存储和取出的元素顺序一致)

TreeSet

TreeSet的底层原理:这是基于红黑树的数据结构实现排序的,增删改查性能都较好

Treeset集合默认的排序规则:

  • 对于数值类型:Integer,Double,默认按照从小到大的顺序进行排序
  • 对于字符,字符串类型:按照字符在ASCII码表中的数字升序进行排序

两种更改排序的方法:

  1. 自然排序:Javabean类实现Comparable接口指定比较规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public clss T implements Comparable<T> {
private String name;
private String id;

...

@Override
public int compareTo(T t) {
//this:表示当前要添加的元素
//t:表示已经在红黑树存在的元素
//返回值:
//负数:认为要添加的元素是小的,存左边
//正数:认为要添加的元素是大的,存右边
//0:认为要添加的元素已经存在,舍弃
return this.getId() - t.getId();
}
}
  1. 比较器排序:创建TreeSet对象时候,传递比较器Comparator指定规则

使用原则:默认使用第一种,如果第一种不能满足当前要求,才使用第二种

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//定义比较规则
int i = o1.length() - o2.length();
i = i == 0 ? o1.compareTo(o2) : i;
//返回值规则和自然排序一样
return i;
}

//lambda表达式改写
TreeSet<String> ts = new TreeSet<>((o1,o2) -> {
//定义比较规则
int i = o1.length() - o2.length();
i = i == 0 ? o1.compareTo(o2) : i;
//返回值规则和自然排序一样
return i;
});
})

使用场景

  1. 想要集合中元素可重复

ArrayList集合,基于数组的

  1. 想要集合中元素去重

HashSet集合,基于哈希表的

  1. 想要集合中元素可重复,而且当前增删操作明显多于查询

LinkedList集合,基于链表的

  1. 想要集合中元素去重,并且保证存取顺序

LinkedHashSet集合,基于哈希表和双链表,效率低于HashSet

  1. 想要集合中元素进行排序

TreeSet集合,基于红黑树,后续也可以用List集合实现排序