Java Collections

应用场景

  • 无法预测存储数据的数量
  • 同时存储具有一对一关系的数据
  • 需要进行数据的增删
  • 数据重复的问题

集合框架的体系结构

Collection - 类的对象

  • List
    • ArrayList
  • Queue
    • LinkedList
  • Set
    • HashSet

Map - key value pairs

  • HashMap

List

  • List是元素有序并且可以重复的集合,成为序列
  • List可以精确的控制每个元素的插入位置,或删除某个位置的元素
  • List的两个主要实现是ArrayList和LinkedList

ArrayList

  • ArrayList底层是由数组实现的
  • 动态增长(倍增),以满足应用程序的需求
  • 在列表尾部插入或删除数据非常有效,增删中间部分的元素则不是非常高效
  • 更适合查找和更新元素
  • ArrayList中的元素可以为null

Set

  • Set是元素无序并且不可以重复的集合

HashSet

  • HashSet是Set的一个重要的实现类,
  • HashSet中的元素无序并且不可以重复
  • HashSet中只允许一个null元素
  • 具有良好的存取和查找性能

迭代器 Iterator

  • Iterator接口可以以统一的方法对各种集合元素进行遍历
  • hasNext()方法检测集合中是否还有下一个元素
  • next()方法返回集合中的下一个元素

Map

  • Map中的数据是以key value的形式存储的
  • key value是以Entry类型的对象实例存在
  • 可以通过key值快速得查找value
  • 一个映射不能包含重复的key, value可以重复
  • 每个key最多映射到一个value

HashMap

  • 给予哈希表得Map实现
  • 允许使用null值和null key
  • key值不允许重复
  • HashMap中的entry对象是无序排列得

集合排序

  • 使用Collections类的sort()方法
  • 使用Comparator和Comparable接口进行排序

Comparator接口

  • 强行对某个对象进行整体排序的比较函数
  • 可以将comparator传递给sort方法 (如Collections.sort或者Arrays.sort)
  • int compare(T o1, T o2) 比较用来排序的两个参数
    • if o1 < o2, return negative integer
    • if o1 == o2, return 0
    • if o1 > o2, return positive integer

Comparable接口

  • 此接口强行对实现他的每个类的对象进行整体排序
  • 这种排序被称为类的自然排序,类的compareTo方法被称为他的自然比较方法
  • 对于集合,通过调用Collections.sort方法进行排序
  • 对于数组,通过调用Arrays.sort方法进行排序
  • int compareTo(T o)
    • 该对象小于,等于或大于指定对象,则分别返回负整数,零或者正整数 (与之前的int compare(T o1, T o2)相同)

Comparator 和 Comparable 的区别

Comparator Comparable
位于java.util包 位于java.lang包
在要比较的类的外部实现该接口,并且可以实现多个不同的Comparator 在要比较的类上实现该接口
调用sort方法时,要指定comparator的实现类 调用sort方法时,只需指定集合名即可

应用场景

  • 如果一个类实现了comparable接口,还希望通过不同的方式进行排序,我们还可以定义额外的Comparator
  • Comparable会作为默认的排序方式,Comparator接口则作为一个扩展的排序方式

TreeSet

  • TreeSet 是一个有序的集合,它支持自然排序个根据实现Comparable和Comparator接口进行排序
  • 当TreeSet用来储存String或者Integer对象时,会按照他们的升序排列
  • TreeSet无法排列自定义类,元素需要实现Comparator或者Comparable来排序

泛型

  • 在Java中增加泛型之前,泛型程序设计使用继承来实现

    • 坏处
      • 需要强制转换
      • 可向集合中添加任意类型的元素,存在风险
  • 泛型的使用

1
List<String> list = new ArrayList<String>();
  • Java SE7及以后的版本中,构造方法中的泛型可以省略
1
List<String> list = new ArrayList<>();

多态与泛型

1
2
3
4
5
class Cat extends Animal {}

List<Animal> list = new ArrayList<Cat>(); // not allowed

List<Number> numbers = new ArrayList<Integer>(); // not allowed
  • 以上代码是不允许的, 变量声明的类型必须匹配传递给实际对象的类型

自定义泛型类

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
public class NumGeneric<T> {
private T num;

public T getNum() {
return num;
}

public void setNum(T num) {
this.num = num;
}
}


// generic class with two generic types
public class TwoNumGeneric<A, B> {
private A num1;
private B num2;

public TwoNumGeneric(A num1, B num2) {
this.num1 = num1;
this.num2 = num2;
}

public A getNum1() {
return num1;
}

public void setNum1(A num1) {
this.num1 = num1;
}

public B getNum2() {
return num2;
}

public void setNum2(B num2) {
this.num2 = num2;
}
}

自定义泛型方法

1
2
3
4
5
6
7
8
public class GenericMethod {

// <T> between public and void declare that this is a generic method
public <T> void printValue(T t) {
System.out.println(t);
}
}