Java Set的操作示例

来源:互联网 发布:市场大数据分析 编辑:程序博客网 时间:2024/06/06 06:52

Set 不能有重复的元素,且是无序的,要有空值也就只能有一个,因为它不允许重复。
Set接口中的方法和Collection一致。

HashSet

HashSet 内部数据结构是哈希表 ,是不同步的。

  • 如何保证该集合的元素唯一性呢?
    是通过对象的hashCode()和equals()方法来保证对象唯一性的。
  • 如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
  • 如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
    如果为true,视为相同元素,不存。
    如果为false,那么视为不同元素,就进行存储。
  1. 如果hashcode函数返回一个定值,即所有对象的hashcode相同时,当尝试插入第二个数据(或以上)时,会发现程序还会去调用equals方法,并且该函数返回false时才回插入HashSet;当hashcode返回不同时会忽略equals函数并直接插入HashSet。
  2. 总结,HashSet先调用对象的hashcode函数来进行散列,当散列到不同位置时,则认为对象不相同且进行插入操作(不用判断equals函数);当散列到同一个位置才会调用对象的equals函数来进行比较,只当equals返回false则认为两个对象不相等才会进行插入操作,否则认为两个对象相同而不进行插入操作。
  3. 自定义对象,重载equals和hashcode时,应该保证两个对象的hashcode的比较结果 和 两个对象的equals函数比较结果,一样。

记住:
1. 如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
2. 一般情况下,如果自定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals(),hashCode()方法,建立对象判断是否相同的依据。

如果HashSet不覆盖equals()和hashCode()方法的话,默认的是使用Object中的equals()和hashCode()方法。Object中的equals方法比较地址的,而不是比较内容,如果添加重复的对象,地址不同,就会认为没有重复的对象,所以比较对象是否相同,必须覆盖equals和hashCode方法

示例:

// 往HashSet集合中存储Person对象,如果姓名和年龄相同,视为同一个人,视为相同元素。@Overridepublic boolean equals(Object obj) { // 判断Person的内容是否相同    if(this == obj) //this只是否为Person自身对象        return true;    if(!(obj instanceof Person)){        throw new ClassCastException("类型转化错误!");    }    Person p = (Person)obj;    return this.name.equals(p.name) && this.age == p.age; //字符创name的内容相同吗,年龄相同吗}@Overridepublic int hashCode() { // 判断Person的hash值是否相同    return name.hashCode()+ age;}
HashSet hs = new HashSet();hs.add(new Person("a",24));hs.add(new Person("b",27));Iterator it = hs.iterator();while(it.hasNext()){    Person p = (Person)it.next();    System.out.println(p.getName()+"...."+p.getAge());}

TreeSet

  使用TreeSet自然排序,如果存放的是自定义对象,必须实现Comparable接口,覆盖里面的compareTo方法,添加元素的时候会进行比较;如果添加的是字符串就不需要覆盖compareTo方法,因为字符串有自己的compareTo方法

public class Person implements Comparable{...}// 以Person对象年龄进行排序,如果年龄相同,就按照姓名排序@Overridepublic int compareTo(Object o) {    if(!(o instanceof Person))        throw new ClassCastException("类型转化错误");    Person p = (Person)o;    int temp = this.age-p.age;    return temp==0 ? (this.name.compareTo(p.name)) : temp; // temp等于0表示年龄相等。}
TreeSet ts = new TreeSet();ts.add(new Person("zhangsan",28));ts.add(new Person("lisi",21));ts.add(new Person("zhouqi",29));ts.add(new Person("zhaoliu",25));ts.add(new Person("wangu",24));ts.add(new Person("zhouqi",29));Iterator it = ts.iterator();while(it.hasNext()){    Person p = (Person)it.next();    System.out.println(p.getName()+":"+p.getAge());}
public class Test {    public static void main(String[] argv) {          TreeSet<String> ts = new TreeSet();        ts.add("abc");        ts.add("zaa");        ts.add("aa");        ts.add("nba");        ts.add("abc");        Iterator it = ts.iterator();        while(it.hasNext()){            System.out.println(it.next());        }    } }// 输出:/*aaabcnbazaa*/

使用TreeSet(Comparator< ? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。

/** * 创建了一个根据Person类的name进行排序的比较器。 * 先按照姓名进行比较,如果姓名相同,再按照年龄进行比较 */public class ComparatorByName implements Comparator {    @Override    public int compare(Object o1, Object o2) {        Person p1 = (Person)o1;        Person p2 = (Person)o2;        int temp = p1.getName().compareTo(p2.getName());        // 姓名相同,再比较年龄        return temp==0 ? p1.getAge()-p2.getAge(): temp;    }}
TreeSet<Person> ts = new TreeSet(new ComparatorByName());ts.add(new Person("zhangsan",28));ts.add(new Person("lisi",21));ts.add(new Person("zhouqi",29));ts.add(new Person("zhaoliu",25));ts.add(new Person("wangu",24));Iterator it = ts.iterator();while(it.hasNext()){    Person p = (Person)it.next();    System.out.println(p.getName()+":"+p.getAge());}
/*  * 对字符串进行长度排序,再比较内容 */public class TreeSetTest {    public static void main(String[] args) {        // 接口内部类        TreeSet ts = new TreeSet(new Comparator<String>() {            @Override            public int compare(String o1, String o2) {                int temp = o1.length() - o2.length();                return temp==0 ? o1.compareTo(o2) : temp;            }        });        ts.add("aaaaa");        ts.add("zz");        ts.add("nbaq");        ts.add("cba");        ts.add("abc");        ts.add("abc");        Iterator it = ts.iterator();        while(it.hasNext()){            System.out.println(it.next());        }    }}// 输出:/*zzabccbanbaqaaaaa*/

转自:http://www.cnblogs.com/200911/p/3948436.html

原创粉丝点击