Java HashSet集合初探(一)

来源:互联网 发布:python 函数定义 编辑:程序博客网 时间:2024/06/07 03:46
/*** @author StormWangxhu* @version 创建时间:2017年11月4日 下午4:03:26**/

Set集合

先来看看集合框架图:
这里写图片描述

  • 与List接口相同点:
    同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的增强,但比Collection接口更加严格!
  • 不同点
    Set接口中的元素 无序、不重复! 至于以什么样的方式保证不重复,其原因后面会说到。

先来结合代码看看HashSet集合中添加重复元素会发生什么:

package com.stormwang.SetTest;import java.util.HashSet;import java.util.Iterator;/*** @author StormWangxhu* @version 创建时间:2017年11月4日 下午4:03:26**/public class HashSetDemo {    public static void main(String[] args) {        // TODO Auto-generated method stub        HashSet set= new HashSet();        //向集合中添加元素        set.add("java");        set.add("Friday");        set.add("java");        Iterator iterator = set.iterator();        while (iterator.hasNext()) {            Object object = (Object) iterator.next();            System.out.println(object);        }       }}

再来看看结果:
这里写图片描述

在代码中,重复了字符串Java,但是运行后,只保留下了一个。
且可以看出,取出顺序和加入顺序也不一致。

原因:

不重复是因为做了很多工作:当向Set集合中添加对象时,add().
步骤:
1、首先调用当前存入对象的hashCode()方法,获得该对象哈希值。
2、根据哈希值确定其存储位置。
3、判断该位置上是否有对象

(1)、无对象,则存入集合。
(2)、有对象 ———->>>调用equal()方法,比较对象是否相等。
(3)、
相等——->>>舍弃该对象
不相等——存入该集合。

下面根据图来理解一下:
这里写图片描述

则要想HashSet正常工作,就必须重写hashCode()方法、equals()方法。

下面以没有重写两个方法演示一下后果:

package com.stormwang.SetTest;/*** @author StormWangxhu* @version 创建时间:2017年11月4日 下午4:35:50**/import java.util.HashSet;import java.util.Iterator;/** * 不复写hashCode()方法、equals()方法 * */public class HashDemo {    public static void main(String[] args) {        // TODO Auto-generated method stub        //创建集合        HashSet set =new HashSet<>();        //创建Student对象        Student student = new Student("1", "Jack");        Student student2 = new Student("2", "mary");        Student student3 = new Student("3", "Rose");        Student student4 = new Student("3", "Rose");        set.add(student);        set.add(student2);        set.add(student3);        set.add(student4);        Iterator iterator = set.iterator();        while (iterator.hasNext()) {            Object object = (Object) iterator.next();            System.out.println(object);        }    }}class Student{    private String id ;    private String name ;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    //构造方法    public Student(String id,String name ) {        this.id = id;        this.name = name ;    }    //    @Override    public String toString() {        return "Student [id=" + id + ", name=" + name + "]";    }}

看一下运行后效果:
这里写图片描述

看到: 出现了相同的值: [ id=3,name=Rose].

原因分析

是因为在类没有重写hashCode()方法,和equals()方法。这样的重复在HashSet集合中理应是不存在的。那么就重写这两个方法试试。
假设id相同的学生是一同一个学生。
看代码:

package com.stormwang.SetTest;/*** @author StormWangxhu* @version 创建时间:2017年11月4日 下午4:35:50**/import java.util.HashSet;import java.util.Iterator;/** * 不复写hashCode()方法、equals()方法 * */public class HashDemo {    public static void main(String[] args) {        // TODO Auto-generated method stub        //创建集合        HashSet set =new HashSet<>();        //创建Student对象        Student student = new Student("1", "Jack");        Student student2 = new Student("2", "mary");        Student student3 = new Student("3", "Rose");        Student student4 = new Student("3", "Rose");        set.add(student);        set.add(student2);        set.add(student3);        set.add(student4);        Iterator iterator = set.iterator();        while (iterator.hasNext()) {            Object object = (Object) iterator.next();            System.out.println(object);        }    }}class Student{    private String id ;    private String name ;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    //构造方法    public Student(String id,String name ) {        this.id = id;        this.name = name ;    }    //    @Override    public String toString() {        return "Student [id=" + id + ", name=" + name + "]";    }    @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + ((id == null) ? 0 : id.hashCode());        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;        Student other = (Student) obj;        if (id == null) {            if (other.id != null)                return false;        } else if (!id.equals(other.id))            return false;        if (name == null) {            if (other.name != null)                return false;        } else if (!name.equals(other.name))            return false;        return true;    }}

再来看看运行结果:

这里写图片描述

重复的没有了,保证了元素的不重复性。也会看到元素的无序性。

再看看HashSet的API

构造函数:
这里写图片描述

方法:

这里写图片描述

HashSet的一些常用方法

添加元素
hashset.add(E e):返回boolean型,如果此 set 中尚未包含指定元素,则添加指定元素;如果此 set 已包含该元素,则该调用不更改 set 并返回 false。

删除元素:
hashset.clear():从此 set 中移除所有元素。
hashset.remove(Object o):如果指定元素存在于此 set 中,则将其移除。
hashset.isEmpty():如果此 set 不包含任何元素,则返回 true。
hashset.contains(Object o):如果此 set 包含指定元素,则返回 true。
hashset.size():返回此 set 中的元素的数量(set 的容量)。

总结:

要想HashSet正常工作,必须重写hashCode()方法和equals()方法。

重写技巧:

右击——–>>source———->>Generate hashCode() and equals()….

就看到这儿吧,晚上再来一个实例练习HashSet()
原创粉丝点击