关闭

java.集合(Ⅲ).Set.HashSet

标签: hashcodeequalsjavaSet
86人阅读 评论(0) 收藏 举报
分类:

Set
|——set:元素是无序的(存入的元素和取出的元素顺序不一定一致),元素不可以重复
|——HashSet:底层数据结构是哈希表
HashSet是怎样保证元素的唯一性呢?
通过元素的hashCode和equals来进行比较的
只有当hashCode返回的哈希值相同时,才会调用equals进行比较

对于判断元素是否存在,以及删除等操作,依赖的方法是hashCode和equals
|——TreeSet
Set集合的功能和Collection是一致的。

⑴HashSet:
哈希表结构特点:在进行储存时,先检测哈希值是否一致,若一致,则检查对象是否一样;若对象不一样,则在该地址下延伸
一块内存将对象进行储存;若对象一样,则第二个添加失败。

import java.util.*;
public class Set {
    public static void write(Object obj)
    {
        System.out.println(obj);
    }

   public static void main(String[] args) {
        HashSet hs =new HashSet();

        write(hs.add("java 01"));
        write(hs.add("java 01"));
        hs.add("java 02");
        hs.add("java 03");
        hs.add("java 04");

        for(Iterator it =hs.iterator();it.hasNext();)
        {
            write(it.next());
        }
    }
}

练习与问题:在自定义内容中去掉重复内容(人的信息)

import java.util.*;
class fPerson
{
    private String name;
    private int age;
    fPerson(String name,int age)
    {
        this.name = name;
        this.age = age;
    }

   public boolean equals(Object obj)
    {
        fPerson p = (fPerson)obj;
        System.out.println(this.name+"..equals.."+p.name);
        return this.name.equals(p.name)&&this.age==p.age;
    }
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
}

public class Set {

public static void write(Object obj)
    {
        System.out.println(obj);
    }

   public static void main(String[] args) {
        HashSet hs =new HashSet();

        hs.add(new fPerson("java01",11));
        hs.add(new fPerson("java02",12));
        hs.add(new fPerson("java01",11));
        hs.add(new fPerson("java03",11));


        for(Iterator it =hs.iterator();it.hasNext();)
        {
            fPerson p =(fPerson)it.next();
            write(p.getName()+"...."+p.getAge());
        }
    }
}

这里写图片描述
由结果可知,equals没有被调用。为什么为什么会这样呢?
解:

package test;

import java.util.*;
class fPerson
{
    private String name;
    private int age;
    fPerson(String name,int age)
    {
        this.name = name;
        this.age = age;
    }
    //hashCode是返回哈希值的函数
    public int hashCode() //因为在HashSet中,如果哈希值不一样,就不会调用equals对 对象
                          //进行比较。所以如果要对自定义内容进行比较,在HashSet中,必须使哈希值一致
    {                        
        return 60;
    }

    public boolean equals(Object obj)
    {
        fPerson p = (fPerson)obj;
        System.out.println(this.name+"..equals.."+p.name);
        return this.name.equals(p.name)&&this.age==p.age;
    }
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
}

public class Set {

    public static void write(Object obj)
    {
        System.out.println(obj);
    }

    public static void main(String[] args) {
        HashSet hs =new HashSet();

        hs.add(new fPerson("java01",11));
        hs.add(new fPerson("java02",12));
        hs.add(new fPerson("java01",11));
        hs.add(new fPerson("java03",11));


        for(Iterator it =hs.iterator();it.hasNext();)
        {
            fPerson p =(fPerson)it.next();
            write(p.getName()+"...."+p.getAge());
        }
    }
}

输出结果

优化版:

package test;

import java.util.*;
class fPerson
{
    private String name;
    private int age;
    fPerson(String name,int age)
    {
        this.name = name;
        this.age = age;
    }
    //hashCode是返回哈希值的函数
    public int hashCode() //因为在HashSet中,如果哈希值不一样,就不会调用equals对 对象
                          //进行比较。所以如果要对自定义内容进行比较,在HashSet中,必须使哈希值一致
    {                        
        System.out.println(this.name+".....hasCode");
        return name.hashCode()+age*39;  //通过返还有对应性的哈希值,能有效的减少比较的次数
        //通过乘一个值,保证不会因为特殊数值导致返回的哈希值一样而增加比较次数
    }

    public boolean equals(Object obj)
    {
        fPerson p = (fPerson)obj; //多态,父类对象转换为子类类型
        System.out.println(this.name+"..equals.."+p.name);//显示比较的过程
        return this.name.equals(p.name)&&this.age==p.age;
    }
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
}

public class Set {

    public static void write(Object obj)
    {
        System.out.println(obj);
    }

    public static void main(String[] args) {
        HashSet hs =new HashSet();

        hs.add(new fPerson("java01",11));
        hs.add(new fPerson("java02",12));
        hs.add(new fPerson("java01",11));
        hs.add(new fPerson("java03",11));


        for(Iterator it =hs.iterator();it.hasNext();)
        {
            fPerson p =(fPerson)it.next();
            write(p.getName()+"...."+p.getAge());
        }
    }
}

这里写图片描述

总的来说
1.HashSet中,比较和删除等主要依靠hashCode和equals两个方法,所以在用HashSet时,覆盖这两个函数极为常见。
2.在HashSet中进行比较时,先比较哈希值,如果相同,再调用equals进行比较

以上。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5946次
    • 积分:277
    • 等级:
    • 排名:千里之外
    • 原创:22篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章分类
    基友博客链接