Hashset

作者: xiaoliman | 来源:发表于2017-08-12 11:44 被阅读0次

1.先清除HashSet是怎么存储数据的.首先,往set里面添加数据的时候,会自动调用hashcode()方法,这个方法就是拿现在对象的hash码和set集合中其他数据的hash码比较(实际是跟哈希表中的记录的 hashcode比较 ) 如果都不相同,就直接添加数据.hash码是根据地址计算的,hash码不同,则地址肯定不同,则肯定不是一个对象.hashcode()就是用来筛选一些地址相同的数据.但是比较的hash码如果有相同的,则会去调用equals(),用来比较具体的属性值,看相同不相同.属性值相同,则不添加.不相同就会添加.
2.如果set中存放的是int类型等一些基本类型 和 String类型的 是不允许内容重复的,即相同的内容如果存放在set里面是不允许的,这是因为这些类型的内容相同的话,他们的地址也相同.

  1. 如果想要实现 HashSet中 属性值相同就认为是同一个对象, 不添加到集合中,则需要重写hashcode和equals方法.因为原本hashcode()就是根据计算地址来进行比较的,所以重写的hashcode()不要计算地址,而是和属性值有关的来进行计算,如果属性值相同,则不会加入到集合中.

4.下面5中hashcode()是自己写的,也可以快捷方式自动生成.如

public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + height;
        return result;
    }

在这里有一个prime.这是为了把数的范围扩大,为了避免属性值不同,但是返回的result相同的情况,这种情况下就会调用equals方法.而实际上属性值不同时,如果把数的范围扩大,就不大有可能出现result相同的情况.(自行体会)

3.person类

package com.qf.demo3;

public class Person {

    private int age;
    private  int height;

    public Person(int age, int height) {
        super();
        this.age = age;
        this.height = height;
    }

    public Person() {
        super();
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    
    @Override
    public String toString() {
        return "Person [age=" + age + ", height=" + height + "]";
    }

    // 是根据内存地址 经过一定的运算得到的
    //重写hashcode 也行者  得到属性值的hashcode 
    @Override
    public int hashCode() {
        //System.out.println("hashcode");
        int result = 0;
        result += age;// int  hashcode值就是自己本身
        result+= height;
        return result;
        // name sex  height 
        //  1   2     3        4 
        // 2    1     3       4 
        /**
         *  和 如果不一样      属性一定不一样
         *  
         *  和 一样    属性值   不一定一样
         *  只有  hashcode 值   相同的时候    才去调用equals方法 来确定 是否真的各个属性值都一样
         *  
         */ 
    }
    
    // 重写以后就是比较的属性值
    @Override
    public boolean equals(Object obj) {
        System.out.println("equals");
        if(obj == this){
            return true;
        }
        if(obj == null){
            return false;
        }
        
        if (obj instanceof Person) {
            Person person = (Person) obj;
            if(this.age == person.age  && this.height == person.height){
                return true;
            }
        }
        return false;
    }
}

main:

package com.qf.demo3;

import java.util.HashSet;

/**
 * Set  无序  不允许重复的
 * 
 * @author Administrator
 *HashSet   :   无序 是展示顺序与存入顺序不同\
 *哈希表: 存储很多的hashcode 
 *
 * 1  存储数据的时候  先  得到  这个数据的hashcode ,  拿这个hashcode  跟  哈希表中 的  记录的 hashcode比较   , 没有相同的 
 *          就认为 是不同的对象, 存入到集合
 * 
 *  如果相同    3+3 = 6
 *          2*3 = 6
 *  
 * 
 *  再去 调用 equals方法   比较每一个属性值 
 *
 *也没有从小到大排序
 */
public class Test {

    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("d");
        set.add("a");
        set.add("w");
        set.add("w");// 不允许 重复
        System.out.println(set);
        
        HashSet<Integer> set2 = new HashSet<>();
        set2.add(8);
        set2.add(10);
        set2.add(1);
        set2.add(8);
        System.out.println(set2);
        
        // 每add一次 就会调用hashcode, 用 要添加的 数据的hash值 跟哈希表中 存储的多个哈希值对比
        // 如果不相同  则一定不是同一个对象  , 就添加到set集合中
        
        
        HashSet<Person> set3 = new HashSet<>();
        set3.add(new Person(7,1));
        set3.add(new Person(2,3));
        set3.add(new Person(2,3));
        set3.add(new Person(3,2));// 只要内容相同 就认为是同一个对象
        
        System.out.println(set3);
    }
}

总结:

  • 需求

  • HashSet中 属性值相同就认为是同一个对象, 不添加到集合中

  • 1 创建类, 重写 hashcode 和 equals
    hashcode 各个属性的hashcode值加和
    equals 每个属性值比较是否相同

  • 2 添加数据时 每添加一个数据就会 调用一次hashcode

  • 3 判断hashcode值 是否已经存在 ,如果不存在 直接将数据加到set集合中 ,不调用equals

  • 4 如果 hashcode值已经存在, 调用equals 方法

  • 如果eqeuals 返回 false 则认为是不同对象 添加到 set 中

  • 如果 equals 返回 true 真正的是 每个属性值 都相同 就认为是同一个对象 不添加到set 中

相关文章

  • java8中hashset源码分析

    分析大纲 hashset实现原理 hashset代码分析 1. hashset实现原理 hashset存储无序,不...

  • HashSet的用法

    java集合——HashSet的用法 一、HashSet的构造 二、HashSet添加元素 三、遍历HashSet...

  • HashSet, LinkedHashSet源码

    目录 HashSet LinkedHashSet HashSet 对于HashSet而言,它是基于HashMap实...

  • Set解析

    概览 上图为HashSet,LinkedSet,TreeSet对比 HashSet 可见HashSet其实就是实现...

  • Java集合之HashSet源码分析

    阅读目录 一、HashSet简介 二、HashSet源码分析 三、HashSet的应用示例代码

  • HashMap 和 HashSet 区别

    看过 HashSet 源码的人就应该知道:HashSet 底层就是基于 HashMap 实现的。(HashSet ...

  • android get external sd card pat

    public static HashSet getExternalMounts() { final HashSet...

  • 聊聊gost的HashSet

    序 本文主要研究一下gost的HashSet HashSet gost/container/set/hashset...

  • HashSet源码分析

    HashSet HashSet概述### HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)...

  • HashSet详解

    引用 java中HashSet详解 Java 编程下 HashSet 存入相同元素的原理 1.向HashSet 集...

网友评论

      本文标题:Hashset

      本文链接:https://www.haomeiwen.com/subject/hibdrxtx.html