精华内容
下载资源
问答
  • hashset去重原理

    2020-04-22 16:55:44
    HashSet去重原理总结: A:HashSet底层数据结构是哈希表(是一个元素为链表的数组) B:哈希表底层依赖两个方法:hashCode()和equals() 执行顺序: 首先比较哈希值是否相同 相同:继续执行equals()方法 返回true:元素...

    HashSet去重原理总结:
    A:HashSet底层数据结构是哈希表(是一个元素为链表的数组)
    B:哈希表底层依赖两个方法:hashCode()和equals()

    执行顺序:
    首先比较哈希值是否相同
    相同:继续执行equals()方法
    返回true:元素重复了,不添加
    返回false:直接把元素添加到集合
    不同:就直接把元素添加到集合

    展开全文
  • HashSet去重原理

    万次阅读 2017-09-07 21:59:09
    HashSet去重原理首先我们来说说HashSet的特点: 它是无序的,即添加的顺序和遍历出来的顺序是不同的 它里面不允许有重复元素,是因为它是基于HashMap实现的 实现了Set接口,由哈希表(实际上是一个HashMap实例)支持...

    HashSet去重原理

    首先我们来说说HashSet的特点:

    • 它是无序的,即添加的顺序和遍历出来的顺序是不同的
    • 它里面不允许有重复元素,是因为它是基于HashMap实现的
    • 实现了Set接口,由哈希表(实际上是一个HashMap实例)支持
    • 底层数据结构是哈希表

    那它是如何保证元素的唯一性的呢?

    答案是依赖两个方法:
    hashCode()equals()方法

    如果我们希望一个集合有去重复的功能, 可以在它的add方法中检查要添加的对象在集合中是否存在,迭代集合中每个元素, 和要添加的比较, 如果相同, 就不存,所以我们来看看add()方法的部分源码解析:
    因为源码太长,我就截取一小部分重要的出来哈!

    private static final Object PRESENT = new Object();
    private transient HashMap<E,Object> map;    
    public boolean add(E e) { 
                return map.put(e, PRESENT)==null;
    }    
    ......
    if (e.hash == hash && ((k = e.key) == key || key.equals(k))){
    ......//e.hash调用了hashCode()方法获得了e元素的hash值
    }

    从源码中我们可以看出:
    它的add()方法实际上调用的是HashMap中的put()方法,把要添加进HashSet中的元素当做key存入,而value则是一个固定值:一个Object类对象。
    先用hashCode()方法获得传入元素的哈希值,在集合中查找是否包含哈希值相同的元素,如果相同,则继续进行比较它们地址值,一般地址值都是不相同的,所以最后会用equals()方法比较对象内的属性值。
    比较结果全为false就存入,如果比较结果有true则不存.

    那如何将自定义类对象存入HashSet进行去重呢?


    • 类中必须重写hashCode()方法和equals()方法
    • equals()方法中比较所有属性
    • hashCode()方法要保证属性相同的对象返回值相同, 属性不同的对象尽量不同,对象的成员变量值相同即为同一个元素

    我用了一个Student类进行说明,类中有name和age属性:
    >重写后的hashCode()方法:
    @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;
    }

    要尽可能的让不同对象的哈希值不相同,因为使用equals()方法进行一系列的判断的前提是要建立在哈希值相同的基础上的,如果哈希值不相同,就直接添加该元素,就不用进行后续的判断了,这样就节省了好多资源;
    那怎样保证hash值尽量不相同呢?
    由重写后的hashCode()方法可以看出:成员变量的值影响了哈希值,所以我们把成员变量的值和哈希值做一系列的运算,更改后相加即可,例如我们可以把它们乘以一些整数
    重写后的equals()方法:

    @Override
        public boolean equals(Object obj) {
            if (this == obj)     //先判断传入的对象地址是否和当前对象一样
              return true;     //如果一样的话,肯定为同一对象,直接返回true
            if (obj == null)       //如果传入的对象为空的话
              return false; //则直接返回false,添加到集合中,因为Set可以存null值
            if (getClass() != obj.getClass())//然后判断字节码文件的对象
              return false;//不相等的话说明两个元素肯定不同,就直接返回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;
        }

    HashSet去重原理总结:

    A:HashSet底层数据结构是哈希表(是一个元素为链表的数组)
    B:哈希表底层依赖两个方法:hashCode()和equals()

    执行顺序:
        首先比较哈希值是否相同
            相同:继续执行equals()方法
                   返回true:元素重复了,不添加
                   返回false:直接把元素添加到集合
            不同:就直接把元素添加到集合

    C:元素唯一性由hashCode()和equals()保证的,二者缺一不可


    展开全文
  • hashSet去重原理

    2019-11-07 16:55:11
    如果地址不一样,直接存入,如果地址一样,就不能通过地址进行判断,还需要开启第二重去重原理。 第二重原理:当地址一样的时候,则使用第二重去重原理,比较对象中的值是否一致。如果值不一致,可以存入,如果地址...

    第一重原理:首先判断两个对象的地址是否一致。如果地址不一样,直接存入,如果地址一样,就不能通过地址进行判断,还需要开启第二重去重原理。
    第二重原理:当地址一样的时候,则使用第二重去重原理,比较对象中的值是否一致。如果值不一致,可以存入,如果地址一样,值也一样则不存入。
    因此,可以直接重写hashCode()和equils()方法,给定hashcCode()返回固定值,实现对象的不重复

    展开全文
  • HashSet 的特点 它是无序的,即添加的...去重原理 依赖两个方法:hashCode()和equals() 如果我们希望一个集合有去重复的功能, 可以在它的add方法中检查要添加的对象在集合中是否存在,迭代集合中每个元素, 和要添加的

    HashSet 的特点

    • 它是无序的,即添加的顺序遍历出来的顺序是不同的
    • 它里面不允许有重复元素,是因为它是基于HashMap实现的
    • 实现了Set接口,由哈希表(实际上是一个HashMap实例)支持
    • 底层数据结构是哈希表(散列表)

    HashSet 的底层是用散列表实现的,散列表的大小默认为16,加载因子为0.75。

    去重原理

    依赖两个方法:hashCode()和equals()

    如果我们希望一个集合有去重复的功能, 可以在它的add方法中检查要添加的对象在集合中是否存在,迭代集合中每个元素, 和要添加的比较, 如果相同, 就不存,所以我们来看看add()方法的部分源码解析:

    private static final Object PRESENT = new Object();
    private transient HashMap<E,Object> map;    
    public boolean add(E e) { 
                return map.put(e, PRESENT)==null;
    }    
    ......
    if (e.hash == hash && ((k = e.key) == key || key.equals(k))){
    ......//e.hash调用了hashCode()方法获得了e元素的hash值
    }
    

    它的add()方法实际上调用的是HashMap中的put()方法,把要添加进HashSet中的元素当做key存入,而value则是一个固定值:一个Object类对象。

    执行顺序:

    1. 首先比较哈希值是否相同

    2. 相同:继续执行equals()方法
      返回true:元素重复了,不添加
      返回false:直接把元素添加到集合

    3. 不同:就直接把元素添加到集合

    元素唯一性由hashCode()和equals()保证的,二者缺一不可

    展开全文
  • Set 去重原理 继承图 |-- SortedSet接口-----TreeSet实现类 set接口------|-- HashSet实现类 |-- LinkedHashSet实现类 源码中 Set.java 定义了 add() 的抽象方法,具体实现需要看 TreeSet 和 HashSet 的实现 // @...
  • java hashset去重原理

    千次阅读 2018-02-27 20:17:25
    下面以set的一个实现类HashSet为例,简单介绍一下set不重复实现的原理: [java] view plain copy print ? package  com.darren.test.overide;    public   class  CustomString {    private  ...
  • php被添加了2次,但是输出的时候只有一次,那么其去重原理是什么呢? public class Test { public static void main(String[] args) { HashSet<String> set=new HashSet<>(); set.add("hello"); set....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,610
精华内容 1,444
关键字:

hashset去重原理