set集合中常用到的两种集合一个是HashSet,一个是TreeSet.
HashSet集合保证元素的唯一性。依赖的是元素的HashCode方法和equals方法。当元素的哈希值不同时元素都有自己的独立位置,不需要再判断元素的equals方法。当元素的哈希值相同时,就要判断元素的内容是否相同,即调用元素的equals方法进行一次比较。如果equals方法返回true,那么是为元素相同不予存储;如果返回false那么这两个元素不相同,会存储在同一哈希值上。
//人对象,如果姓名,年龄相同视为同一个对象。就不进行存储了。 class Person { private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } public int hashCode() { System.out.println(this+"......hashCode"); final int NUMBER = 38; return name.hashCode()+age*NUMBER; //return 1; } /**/ public boolean equals(Object obj) { System.out.println(this+"....equals...."+obj); if(this==obj) return true; if(!(obj instanceof Person)) return false; Person p = (Person)obj; return this.name.equals(p.name) && this.age==p.age; /**/ //return true; } public String getName() { return name; } public int getAge() { return age; } public String toString() { return name+"::"+age; } }TreeSet除了可以保证元素的唯一性,还可以对Set集合中的元素进行排序,即同时具备比较性。它的数据结构是二叉树数据结构。这种结构,可以提高排序性能。其唯一性是根据比较方法的返回值确定的。只要返回的是0.就代表元素重复。使用TreeSet排序时,对象需要自身具备唯一性与比较性,所以自定义对象的唯一性与比较性至关重要。一般有两种方式实现。第一种是实现Comparable接口并覆写CompareTo方法,如下(按照年龄排序,如果年龄相同按照姓名排序)
class TreeSetDemo2 { public static void main(String[] args) { TreeSet ts = new TreeSet(); ts.add(new Person("lisi1",21)); ts.add(new Person("lisi4",24)); ts.add(new Person("lisi2",24)); ts.add(new Person("lisi0",20)); ts.add(new Person("lisi8",28)); System.out.println(ts); } } class Person implements Comparable { private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public int compareTo(Object obj) { Person p = (Person)obj; //方法三: int num = new Integer(this.age).compareTo(new Integer(p.age)); return num == 0?this.name.compareTo(p.name):num; /* //方法二: int num = this.age-p.age; return num == 0?this.name.compareTo(p.name):num; */ /* //方法一: if (this.age>p.age) { return 1; } else if (this.age==p.age) { return this.name.comepareTo(p.name); } else return -1; */ } public String toString() { return name+"::"+age; } }第二种方式是定义一个比较器,让集合自身具备比较性。即定义一个类,实现Comparator接口。覆盖compare方法。将Comparator接口的子类对象作为参数传递给TreeSet的构造函数。,如: class TreeSetDemo3 { public static void main(String[] args) { TreeSet ts = new TreeSet(new CompareByName()); ts.add(new Person("lisi1",21)); ts.add(new Person("lisi4",29)); ts.add(new Person("lisi2",67)); ts.add(new Person("lisi8",28)); ts.add(new Person("lisi0",20)); System.out.println(ts); } } //自定义一个比较器。 class CompareByName implements Comparator { public int compare(Object o1,Object o2) { Person p1 = (Person)o1; Person p2 = (Person)o2; int num = p1.getName().compareTo(p2.getName()); return num==0?p1.getAge()-p2.getAge():num; } } class Person implements Comparable { private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } //人的自然排序是按照年龄排序 public int compareTo(Object obj) { Person p = (Person)obj; int num = new Integer(this.age).compareTo(new Integer(p.age)); return num==0?this.name.compareTo(p.name):num; } public String getName() { return name; } public int getAge() { return age; } public String toString() { return name+"::"+age; } } 注意,那么描述该类对象时, 一定要复写几个方法. 1,hashCode() 2,equals() 3,toString() 4,最好实现Comparable接口让该类具备自然排序功能。建立对象自身判断是否相同的依据,同时让对象具备基本的比较性。