Set接口
Set与Collection的结构基本上完全一样,不同在于无序,不能重复
Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说两个对象用equals方法比较返回true,Set就不会接受这两个对象。
/** * Set演示 * 2014-4-6 */ import java.util.HashSet; import java.util.Set; public class SetDemo { public static void main(String[] args) { Set s=new HashSet(); s.add("123"); //添加两个相同的元素,会返回false boolean m=s.add("123"); System.out.println(m); System.out.println(s); } }
程序运行结果:
false [123]
HashSet
内部结构为哈希表
元素无序,不是同步的(注意线程安全问题),集合元素值可以为null
当向 HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该值来决定该对象在HashSet中的存储位置。如果有两个元素通过equals方法比较返回true,但它们的hashCode方法返回值不相等,HashSet将会把它们存储在不同的位置。也就是说HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode方法返回值也相等。
import java.util.HashSet; /** * HashSet类判断两元素相等实例 * 2014-4-6 * @author Administrator * */ public class HashSetDemo { /** * @param args */ public static void main(String[] args) { HashSet set=new HashSet(); set.add(new A()); set.add(new A()); set.add(new B()); set.add(new B()); set.add(new C()); set.add(new C()); System.out.println(set); } } class A{ @Override public boolean equals(Object obj){ return true; } } class B{ @Override public int hashCode(){ return 1; } } class C{ @Override public int hashCode(){ return 2; } public boolean equals(Object obj){ return true; } }
程序运行结果:
[B@1, B@1, C@2, A@4f1d0d, A@18a992f]
Object类提供的toString方法总是返回该对象实现类的类名+@+hashCode(16进制数)值,所以可以看到上面程序输出的结果。可以通过重写toString方法来输出自己希望的形式。
即使2个A对象通过equals比较返回true,但HashSet依然把它们当成2个对象;即使2个B对象的hashCode()返回相同值,但HashSet依然把它们当成2个对象。即如果把一个对象放入HashSet中时,如果重写该对象equals()方法,也应该重写其hashCode()方法。其规则是:如果2个对象通过equals方法比较返回true时,这两个对象的hashCode也应该相同。
TreeSet:
以对集合中的元素进行排序。是不同步的
TreeSet支持两种排序方法:自然排序和定制排序。默认情况下TreeSet采用自然排序
自然排序
TreeSet会调用集合元素的comparaTo(Object obj)方法来比较元素之间大小关系,然后将集合元素按升序排列,这就是自然排序。
Java提供了一个Comparable接口,该接口中定义了一个comparaTo(Object obj)方法,返回一个整数值,实现了该接口的类的对象就可以比较大小。如:obj1.comparaTo(obj2),如果该方法返回0,则表明这两个对象相等;返回正整数,则表明obj1大于obj2;返回一个负整数,则表明obj1小于obj2。
如果试图把一个对象添加进TreeSet时,则该对象的类必须实现CompareTo接口,否则程序将会出现异常
import java.util.TreeSet; /** * TreeSetTreeSet添加两个相同类型的对象错误示范 * 2014-4-7 * @author Administrator * */ public class TreeSetDemo { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TreeSet set=new TreeSet(); set.add(new Error()); //添加两个相同元素,会引发java.lang.ClassCastException异常 set.add(new Error()); } } class Error{ }
向TreeSet集合中添加元素时,只有第一个元素可以无需实现CompareTo接口,后面添加的所有元素都必须实现CompareTo接口。另外向TreeSet中添加的应该是同一个类的对象,不然不好比较,否则也会引发ClassCastException异常。
对于TreeSet集合而言,它判断两个对象不相等的标准是:两个对象通过equals方法比较返回false,或通过compareTo比较没有返回0,即使两个对象是同一个对象,TreeSet也会把他们当成两个对象处理。
import java.util.TreeSet; /** * TreeSet添加两个相同类型的对象示范 * 2014-4-7 * @author Administrator * */ public class TreeSetDemo2 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TreeSet set=new TreeSet(); Z z=new Z(10); set.add(z); boolean flag=set.add(z); System.out.println(flag); System.out.println(set); } } class Z implements Comparable{ int age; public Z(int age){ this.age=age; } public boolean Equals(Object obj){ return false; } public int compareTo(Object o) { // TODO Auto-generated method stub return 1; } }
定制排序
使用定制排序时,TreeSet对集合元素排序时不管集合元素本身大小,而是由Comparator对象负责集合元素的排序规则。