黑马程序员技术交流社区

标题: Set集合接口 [打印本页]

作者: dadai5ai    时间: 2015-7-31 09:58
标题: Set集合接口

Set之中保存的元素是不能够有重复,但是Set接口并不像List接口那样对Collection进行了方法的扩充,而是完整的继承了Collection接口的所有方法,那么也就意味着,在之前使用的get()方法无法使用了。

         Set子接口之中重要使用两个常用的子类:HashSet、TreeSet。

4.1、散列存放的子类:HashSet(90%)

       Hash是一种散列算法,指的保存数据没有序列。

package cn.mldn.demo;
import java.util.HashSet;
import java.util.Set;
public class TestDemo {
    public static void main(String[] args) throws Exception {
        Set all = new HashSet() ;
        all.add("HELLO") ;
        all.add("HELLO") ;  // 保存了重复数据
        all.add("WORLD") ;
        all.add("小金子") ;
        all.add("小谢子") ;
        System.out.println(all);
    }}

         使用HashSet是不能够保存重复数据的。而且保存的数据没有任何的顺序。

4.2、排序存放的子类:TreeSet(10%)

       如果希望里面的数据排序,则可以使用TreeSet子类。

package cn.mldn.demo;
import java.util.Set;
import java.util.TreeSet;
public class TestDemo {
    public static void main(String[] args) throws Exception {
        Set all = new TreeSet() ;
        all.add("B") ;
        all.add("D") ;  // 保存了重复数据
        all.add("E") ;
        all.add("A") ;
        all.add("C") ;
        System.out.println(all);
    }}

        但是对于排序一般意义不大,所以使用的时候还是以HashSet为主。

4.3、关于数据排序的说明

         使用TreeSet可以实现集合中数据排序的保存,那么在之前使用的是String型数据,下面使用自定义类。但是这个类如果要想正常的使用TreeSet保存,那么一定要在此类上实现java.lang.Comparable接口,以区分大小。

        但是在此时覆写compareTo()方法的时候必须注意到:所有的属性都必须进行比较,否则就会出现部分属性内容相同也会认为是同一对象的情况,造成数据的保存错误。

范例:使用自定义类

package cn.mldn.demo;
import java.util.Set;
import java.util.TreeSet;
class Person implements Comparable {
    private String name ;
    private int age ;
    public Person(String name,int age) {
        this.name = name ;
        this.age = age ;
    }
    @Override
    public String toString() {
        return "姓名:" + this.name + ",年龄 :" + this.age + "\n" ;
    }
    @Override
    public int compareTo(Person o) {
        if (this.age > o.age) {
            return -1 ;
        } else if (this.age < o.age) {
            return 1 ;
        }
        return this.name.compareTo(o.name);
    }
}
public class TestDemo {
    public static void main(String[] args) throws Exception {
        Set all = new TreeSet() ;
        all.add(new Person("张三",20)) ;
        all.add(new Person("李四",21)) ;
        all.add(new Person("赵六",21)) ; // 年龄重复
        all.add(new Person("王五",19)) ;
        all.add(new Person("王五",19)) ; // 彻底重复
        System.out.println(all);
    }
}

        通过此时的程序也可以得出一个结论:TreeSet使用过程之中一定要使用到Comparable接口,而且TreeSet集合里面是依靠Comparable接口的compareTo()方法返回的数据来区分是否为重复数据。

4.4、关于重复数据的说明

       Set子接口之中不允许保留重复数据,之前使用的TreeSet子类虽然依靠了Comparable接口进行重复数据判断,但是此判断的方式也只是针对于TreeSet这种排序结构起作用,而真正意义上的排序操作是不依靠接口的,而是依靠Object类之中的两个方法:

                   · 取得对象的hash码:public int hashCode()

                  · 对象比较:public boolean equals(Object obj)

         在判断对象是否重复的过程之中,其基本流程如下:

                   · 首先使用要查询对象的hashCode与集合之中的保存对象的每一个hashCode进行比较;

                   · 如果hashCode相同,则再使用equals()方法进行内容的比较。



范例:重复对象判断

package cn.mldn.demo;
import java.util.HashSet;
import java.util.Set;
class Person {
    private String name ;
    private int age ;
    public Person(String name,int age) {
        this.name = name ;
        this.age = age ;
    }
    @Override
    public String toString() {
        return "姓名:" + this.name + ",年龄 :" + this.age + "\n" ;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}
public class TestDemo {
    public static void main(String[] args) throws Exception {
        Set all = new HashSet() ;
        all.add(new Person("张三",20)) ;
        all.add(new Person("李四",21)) ;
        all.add(new Person("赵六",21)) ; // 年龄重复
        all.add(new Person("王五",19)) ;
        all.add(new Person("王五",19)) ; // 彻底重复
        System.out.println(all);
    }
}

        任何情况下如果是对象的重复判断,永恒都使用hashCode()和equals()。








欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2