Hashset

2017-08-12  本文已影响0人  xiaoliman

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);
    }
}

总结:

上一篇 下一篇

猜你喜欢

热点阅读