Java集合类主要由两个接口派生出来Collection和Map,java集合可以分成四大类:Set、Map、Queue、List四大类,这次我要分别来介绍这四大类,以及这几类的性能比较。
List集合
首先List集合代表一个元素有序、可重复的集合,允许使用重复元素,可以通过索引来访问指定的集合元素。
首先我们要明白,List是作为Collection接口的一个子接口,所以List是一个接口。它下面的实现类是ArrayList和Vector。ArrayList集合是我们经常使用的,ArrayList和Vector都是基于数组实现的List类,性能比较不错。
ArrayList和Vector的区别:
最显著的区别在于Vector是线程安全的,所以性能自然而然比较差,对于ArrayList如果当多个线程访问同一个ArrayList集合时,如果有超过一个线程修改了ArrayList集合,则必须保证集合的同步性。Vector还有一个Stack子类,如果想模拟栈的"后进先出"也可以用之实现。(小编不推荐)
Set集合
明确一点Set集合不允许包含相同的元素,如果试图把两个相同的元素加入到一个Set集合中,则会添加失败,add返回false。再往深了挖掘,Set判断两个对象相同时使用==运算符,而不是equals方法,也就是说,只要两个对象用equals方法比较返回true,set就不会接受这两个对象;反之,只要两个对象用equals方法比较返回false,则会接受。
Set是接口,那么下面的主要实现类包括哪些呢?
HashSet是Set接口的典型实现,也是我们经常使用的,特点是不保证元素的排列顺序,顺序有可能发生变化,而且不是同步的,所以HashSet也是线程不安全的。再往深处挖,当向HashSet中存入一个元素时,HashSet会调用该对象的hashCode方法,来得到该对象的hashcode值,然后根据code值来决定该对象HashSet中的存储位置,如果有两个元素通过equals()方法比较返回true,但是它们的hashCode()方法返回值不相等,HashSet就会把他们存储在不同的位置,依旧会添加成功的。所以HashSet中可以添加相同的对象,知识位置不同而已。代码如下:
import java.util.TreeSet;
class R{
int count;
public R(int count){
this.count = count;
}
public String toString(){
return "R[count:" + count +"]";
}
public boolean equals(Object obj){
if(this ==obj){
return true;
}
if(obj != null && obj.getClass() == R.class){
R r = (R)obj;
if(r.count == this.count){
return true;
}
}
return false;
}
public int hashCode(){
return this.count;
}
}
public class HashSetTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new R(5));
hs.add(new R(-3));
hs.add(new R(9));
hs.add(new R(-2));
System.out.println(hs);
//取出第一个元素
Iterator it = hs.iterator();
R first = (R) it.next();
//为第一个元素的count实例变量赋值
first.count = -3;
//再次取出hashset集合 集合元素有重复元素
System.out.println(hs);
//删除count为-3的R对象
hs.remove(new R(-3));
//可以看到被删除了一个R元素
System.out.println(hs);
//输出false
System.out.println("hs是否包含count为-3的R对象?" + hs.contains(new R(-3))
);
System.out.println("hs是否包含count为5的R对象?" + hs.contains(new R(5)));
}
}
HashSet的子类是LikedHashSet,顾名思义是链条维护,比较一下他们的性能,如果想执行插入,因为在插入时,LinkedHashSet要维护元素的插入顺序,自然性能较低,但是如果想迭代访问Set里的全部元素,LinkedHashSet的性能较好。
TreeSet是SortedSet接口的实现类,如果想随机向集合中添加四个Integer对象,5,2,10,-9,打印出的顺序treeSet会自动给排序。看下面代码
import java.util.TreeSet;
public class HashSetTest {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(5);
ts.add(2);
ts.add(10);
ts.add(-9);
System.out.println(ts);
System.out.println(ts.first());
System.out.println(ts.last());
System.out.println(ts.headSet(4));
System.out.println(ts.tailSet(5));
System.out.println(ts.subSet(-3, 4));
}
}
最后比较一下TreeSet和HashSet的性能,HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。我们通常都应该使用HashSet,在我们需要排序的功能时,TreeSet会通过红黑树算法进行排序,我们更会考虑TreeSet。
下篇文章Queue和Map集合。