一、HashSet
1. 虑重功能特性(HashMap实现)
2. put(key) 如果重复返回false
/** * Adds the specified element to this set if it is not already present. * More formally, adds the specified element <tt>e</tt> to this set if * this set contains no element <tt>e2</tt> such that * <tt>(e==null ? e2==null : e.equals(e2))</tt>. * If this set already contains the element, the call leaves the set * unchanged and returns <tt>false</tt>. * * @param e element to be added to this set * @return <tt>true</tt> if this set did not already contain the specified * element */ public boolean add(E e) { return map.put(e, PRESENT)==null; // 重复返回false }
二、TreeSet(有序的,基于TreeMap红黑树实现)
问题1:
如果试图把一个对象添加到TreeSet时,则该对象的类必须实现Comparable接口,否则程序会抛出异常java.lang.ClassCastException。
如下:
public static void main(String[] args) { TreeSet t1= new TreeSet(); t1.add(new Err()); t1.add(new Err()); //Exception in thread "main" java.lang.ClassCastException: } class Err{ }
原因:
TreeSet集合中添加两个Err对象,添加第一个对象时,TreeSet里没有任何元素,所以不会出现任何问题;当添加第二个Err对象时,TreeSet就会调用该对象的compareTo(Object obj)方法与集合中的其他元素进行比较—如果其对应的类没有实现Comparable 接口,则会引发ClassCastException异常。
问题2:
在实现compareTo(Object o)方法时,都需要将被比较对象obj强制类型转换成相同类型,因为只有相同类的两个示例才会比较大小。
当试图把一个大对象添加到TreeSet集合时,TreeSet会调用该对象的compareTo(Object o)方法与集合中的其他元素进行比较—这就要求集合中的其他元素与该元素是同一类的示例,否则抛出ClassCaseException异常。
总之一句话,如果希望TreeSet能够正常运行,TreeSet只能添加同一类型对象。
错误示例:
public static void main(String[] args) { TreeSet t2 = new TreeSet(); t2.add("hello"); t2.add(1); //java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
TreeSet判断标准:
TreeSet判断两个对象是否相等的唯一标准是:两个对象通过compareTo(Object o)方法比较是否返回0 —如果通过compareTo(Object o)方法比较返回0,TreeSet则会认为它们相等:否则就认为它们不相等
例子:
import java.util.*; /* class Person implements Comparable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Object o) { // TODO Auto-generated method stub if (o instanceof Person == false) return 0; Person p = (Person)o; int t = this.name.compareTo(p.name); if(t != 0)return t; return this.age - p.age; } public String toString(){ return name + ":" + age; } } */ class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return name + ":" + age; } public String getName(){ return this.name; } public int getAge(){ return this.age; } } class K implements Comparator { @Override public int compare(Object a, Object b) { // TODO Auto-generated method stub if (a instanceof Person == false || b instanceof Person == false) return 0;// 因为如果a,b都不是Person类,那么已经超出了该方法判定的范围,我们只能假定其相等,0表示相等 Person p1 = (Person) a; Person p2 = (Person) b; int t = p2.getName().compareTo(p2.getName()); if (t != 0) return t; return p1.getAge() - p2.getAge(); } } public class TreeSetTEST { public static void main(String[] args) { // Set<Person> a = new TreeSet<Person>(); Set<Person> a = new TreeSet<Person>(new K()); a.add(new Person("hao", 10)); a.add(new Person("hao", 20)); a.add(new Person("hao", 30)); a.add(new Person("hao", 10)); a.add(new Person("zhang", 10)); a.add(new Person("zhang", 11)); a.add(new Person("zhang", 20)); a.add(new Person("li", 40)); System.out.println(a); } }