java集合类主要由两个接口派生:Collection 和 MapCollection:Set(无序集合,元素不可重复)、Queue、List(有序集合,元素可以重复)。
Map:HashMap、Hashtable、TreeMap。
1、Set集合
Set集合不允许包含相同的元素,Set判断两个对象相同不是使用==运算符,而是根据equals方法。
1.1、HashSet
HashSet不是同步的,如果多个线程同时访问,必须通过代码保证其同步。
HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值也相等。
//类A的equals方法总是返回true,但没有重写其hashCode()方法
class A{
public boolean equals(Object obj){
return true;
}
}
//类B的hashCode()方法总是返回1,但没有重写其equals()方法
class B{
public int hashCode(){
return 1;
}
}
//类C的hashCode()方法总是返回2,且重写了其equals()方法
class C{
public int hashCode(){
return 2;
}
public boolean equals(Object obj){
return true;
}
}
public class HashSetTest{
public static void main(String[] atgs){
HashSet books = new HashSet();
books.add(new A());
books.add(new A());
books.add(new B());
books.add(new B());
books.add(new C());
books.add(new C());
System.out.println(books);
}
}
上面程序结果为:
[B@1,B@1,C@2,A@5483cd,A@9931f5]
当把一个对象放入HashSet中时,如果需要重写equals()方法,则也应该重写其hashCode()方法。
LinkedHashSet类是HashSet的子类,它使用链表维护元素的次序,当遍历LinkedHashSet中的元素时,会按元素的添加顺序来访问集合中的元素。
2.2、TreeSet
TreeSet类是SortedSet接口的实现类,可以确保元素处于排序状态。与HashSet集合采用hash算法来决定元素的存储位置不同,TreeSet采用红黑树的数据结构来存储集合元素。Tree支持两种排序方法:自然排序和定制排序。默认为自然排序。
自然排序:TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后进行升序排列。如果试图把一个对象添加到TreeSet时,则该对象的类必须实现Comparable接口,否则程序将会抛出异常。
定制排序:如果需要实现定制排序,例如以降序排列,则可以通过Comparator接口的帮助。
class M{
int age;
public M(int age){
this.age = age;
}
public String toString(){
return "M[age:]"+age+"]";
}
}
public class TreeSetTest{
public static void main(String[] args){
TreeSet ts = new TreeSet(new Comparator(){
public int compare(Object o1,Object o2){
M m1 = (M)o1;
M m2 = (M)o2;
return m1.age>m2.age?-1:m1.age<m2.age?1:0;
}
});
ts.add(new M(5));
ts.add(new M(-3));
ts.add(new M(9));
System.out.println(ts);
}
}
结果为:M[age:9], M[age:5],M[age:-3]