概述
- List,Set,Map都是接口,前两个继承Collection接口,Map为独立的接口。
- Set下面有HashSet,LinkedHashSet,TreeSet
- List下面有ArrayList,Vector,LinkedList
- Map下面有Hashtable,LinkedHashMap,HashMap,TreeMap
- Collection接口下面还有个Queue接口,有PriorityQueue类
- LinkedList既可以实现Queue接口,也可以实现List接口.只不过呢, LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。
List有序,可重复
ArrayList优点:底层数据结构是数组,查询快,增删慢。缺点线程不安全,效率高。
Vector优点:底层是数组,查询快,增删慢。缺点线程安全,效率低。
LinkedList优点:底层是链表,查询慢,增删快。缺点线程不安全,效率高。
Set无序,唯一
HashSet:底层数据结构是哈希表(无序,唯一)。如何保证元素唯一性?依赖两个方法:hashCode()和equals()。主要用来排序。
LinkedHashSet:底层数据结构是链表和哈希表。(FIFO插入有序,唯一)由链表保证元素有序,由哈希表保证元素唯一。主要用来保证FIFO有序的集合。
TreeSet:底层数据结构是红黑树。(唯一,有序)1.如何保证元素排序:自然排序,比较器排序。2.如何保证元素唯一性:根据比较的返回值是否是0来决定。通用的存储数据的集合。
唯一吗?
是:Set
排序吗?
是:TreeSet或LinkedHashSet
否:HashSet
如果你知道是Set,但是不知道是哪个Set,就用HashSet。
否:List
要安全吗?
是:Vector
否:ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
如果你知道是List,但是不知道是哪个List,就用ArrayList。
Map接口
Map接口实现了三个重要的类,分别是HashMap、TreeMap和HashTable
- TreeMap是有序的,HashMap和HashTable是无序的。
- Hashtable的方法是同步的,HashMap的方法不是同步的,这是两者最主要的区别。
这就意味着:
hashtable是线程安全的,HashMap不是线程安全的。
HashMap效率较高,HashTable效率较低。
如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap。 查看Hashtable的源代码就可以发现,除构造函数外,Hashtable的所有 public 方法声明中都有 synchronized关键字,而HashMap的源码中则没有。
Hashtable不允许null值,HashMap允许null值(key和value都允许)
父类不同:Hashtable的父类是Dictionary,HashMap的父类是AbstractMap
TreeSet的排序
1.基本数据类型可以直接排序
2.引用数据类型可以使用自然排序和比较器排序
2.1自然排序:例如Student类中实现Comparable接口,重写Comparable接口中的Compareto方法
public class Student implements Comparable<Student>{
private String name;
private int age;
public int compareTo(Student s){
int num=this.name.length()-s.name.length();
int num1=num==0?this.name.compareTo(s.name):num;
int num2=num1==0?this.age-s.age:num1;
return num2;
}
}
2.2比较器排序:单独创建一个比较类,这里以MyComparator为例,并且要让他继承Comparator接口;重写Comparator接口中的Compare接口。
public class MyComparator implements Comparator<Student>{
public int compare(Student s1,Student s2){
int num=s1.getName().length()-s2.getName().length();
int num1=num==0?s1.getName().compareTo(s2.getName()):num;
int num2=num1==0?s1.getAge()-s2.getAge():num2;
}
}