15--API-Set-->HashSet

Set(接口)

概述

set是一个不包含重复元素的集合, 至多包含一个null

set中不能存放重复元素, 常用来去重

数据无序(因为set集合没有下标)。

Set接口的特点:

不重复, 无序, 无索引

常用方法:

返回类型 方法名 解释
boolean add(E e) 添加元素。
boolean addAll(Collection c): 把小集合添加到大集合中 。
boolean : contains(Object o) 如果此 collection 包含指定的元素,则返回 true。
boolean isEmpty() : 如果此 collection 没有元素,则返回 true。
boolean remove(Object o) : 从此 collection 中移除指定元素的单个实例。
Iterator iterator(): 返回在此 collection 的元素上进行迭代的迭代器。
int size() : 返回此 collection 中的元素数。
Objec[] toArray(): 返回对象数组

HashSet(实现类)

概述:

HashSet是Set接口的实现类, 可以使用Set接口的所有功能, 拥有Set接口的特点, 数据无序, 不重复, 无索引

特点

HashSet底层是哈希表(也叫散列表). 实际上底层维护了一个HashMap

它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。

常用构造器

方法 说明
HashSet() 无参构造

常用方法:

返回类型 方法名 解释
boolean add(E e) 添加元素。
boolean addAll(Collection c): 把小集合添加到大集合中 。
boolean : contains(Object o) 如果此 collection 包含指定的元素,则返回 true。
boolean isEmpty() : 如果此 collection 没有元素,则返回 true。
boolean remove(Object o) : 从此 collection 中移除指定元素的单个实例。
Iterator iterator(): 返回在此 collection 的元素上进行迭代的迭代器。
int size() : 返回此 collection 中的元素数。
Objec[] toArray(): 返回对象数组

自定义对象去重:

注意: 去重自定义对象的时候, equals()和hashCode()必须都重写, 这样的话才可以识别两个对象是否相等, 才能达到去重的目的

  • hashCode() 是为了让底层运算哈希值是, 可以根据对象的属性值运算, 如果两个对象的属性值一样, 就可以认为是相等的hash值
  • equals() 是为了让底层在判断两个对象是否相等时, 让equals()返回true.
//--源码摘抄:HashMap中634行显示。必须满足以下判断条件,才能给自定义对象去重。
if (p.hash == hash &&((k = p.key) == key ||(key!=null&&key.equals(k))))

测试去重

public class Test5_HashSet2 {
    public static void main(String[] args) {
        //1、创建HashSet对象
        HashSet<Student> set = new HashSet<>();
        Student s1 = new Student("jack",18);
        Student s2 = new Student("rose",20);
        Student s3 = new Student("tony",30);
        //2、加入set中
        set.add(s1);
        set.add(s2);
        set.add(s3);
        //3、set集合不是可以去重吗?-- 能不能把自定义的对象去重呢?-- 暂时没去重!!
        Student s4 = new Student("jack",18);
        //4、怀疑add()在添加自定义的对象时,没有根据属性去重!!
        //if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
        //5、为了使两个对象间的hash值一致,我们需要把只要new一次就计算一个hash值这种默认实现方式改掉。
        //这时,需要重写hashCode()让此方法运算出来的hash值可以根据对象的属性值运算。
        set.add(s4);
        System.out.println(s1.hashCode());
        System.out.println(s4.hashCode());	
        System.out.println(set);
    }
}
//创建Student类
class Student{
    public Student() {}
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    private String name ;
    private int age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
    //右键-source-generator equals() and hashCode()-ok

    //5、为了使两个对象间的hash值一致,我们需要把只要new一次就计算一个hash值这种默认实现方式改掉。
    //这时,需要重写hashCode()让此方法,运算出来的hash值可以根据对象的属性值运算。
    @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;
    }
    //6、为了让两个对象间,比较属性值,需要提供重写的equals()
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) 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;
    }						
}

posted on 2020-05-21 15:37  liqiangbk  阅读(129)  评论(0编辑  收藏  举报

导航