先概括三个接口的特点:
Set:不重复,不排序(TreeSet会排序)
List:索引排序,可以重复
Map:键值对,无重复键
接着是表格对比:
重复 排序 线程安全 特点
------------------------------------------------------------------------------------------------------------------------
Map: HashMap:无重复键 不排序 不安全 适用于大部分key-value的存取场景
HashTable:无重复键 不排序 安全 有安全需求才使用
TreeMap:无重复键 排序 不安全 适用于需排序存放的key-value场景
------------------------------------------------------------------------------------------------------------------------
Set: HashSet: 不重复 不排序 不安全 适用于不排序的非重复元素的存放
TreeSet: 不重复 排序 不安全 适用于 排序的非重复元素的存放
-------------------------------------------------------------------------------------------------------------------------
List: ArrayList: 重复 索引排序 不安全 查询快
LinkedList: 重复 索引排序 不安全 增删快
Vector: 重复 索引排序 安全 效率没有ArrayList高
-------------------------------------------------------------------------------------------------------------------------
先说List接口:
ArrayList底层是Object数组实现,因为数组在内存地址中是连续的,所以查询快。但是增删的时候数据需要前移或者后移(复制),所以慢。
LinkedList底层是用链表实现,查询慢,因为每次查询有要遍历链表。增删快是因为只要改变插入位置前后元素的指向即可。
Vector底层是Object数组实现的,和ArrayList差不多,但是因为是线程安全的,所以操作效率低。
Set接口:
HashSet底层使用哈希表实现,存取快。HashSet添加元素的过程如下:
调用添加的元素的hashCode方法计算存放的位置,然后如果位置上没有元素就存入,如果有元素就调用equals方法。equals方法返回true就说明元素重复,不添加,equals返回false就添加元素。
例子:
import java.util.HashSet;
public class Demo001 {
public static void main(String[] args) {
HashSet<Student> set = new HashSet<>();
set.add(new Student(3, "小明"));
set.add(new Student(3, "小明"));
System.out.println(set);
}
}
class Student {
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
return this.age + this.name.hashCode();
}
@Override
public boolean equals(Object obj) {
return this.age == ((Student) obj).getAge();
}
@Override
public String toString() {
return "age=" + age + ";name=" + name;
}
}
如果注释了hashCode和equals方法,那么返回结果为
[age=3;name=小明, age=3;name=小明]
如果重写了hashCode和equals方法,那么返回结果为
[age=3;name=小明]
接着是TreeSet,底层是二叉树。特点是集合中的元素会排序。那么要排序就必须满足以下三者之一:
1、TreeSet中的元素具有自然顺序。
2、元素所属的类实现了Comparable接口
3、创建TreeSet对象的时候传入一个比较器对象
Map接口:
HashMap底层是哈希表,用于存放键值对数据,key和value都是为null。
HashTable是安全的HashMap,但是key和value都不为null。
TreeMap底层是二叉树,元素的key会被排序。
这里先总结那么多。毕竟没有看过源码,只是总结所学所用。将来有机会再补上源码解读。