精华内容
下载资源
问答
  • 主要介绍了python中的set实现不重复的排序原理,需要的朋友可以参考下
  • Set 不重复实现原理

    千次阅读 2018-08-31 15:35:59
    Java中的set是一个包含重复元素的集合,确切地说,是包含e1.equals(e2)的元素对。Set中允许添加null。Set不能保证集合里元素的顺序。 在往set中添加元素时,如果指定元素存在,则添加成功。也就是说,如果set...

    Java中的set是一个不包含重复元素的集合,确切地说,是不包含e1.equals(e2)的元素对。Set中允许添加null。Set不能保证集合里元素的顺序。

    在往set中添加元素时,如果指定元素不存在,则添加成功。也就是说,如果set中不存在(e==null ? e1==null : e.queals(e1))的元素e1,则e1能添加到set中。

    下面以set的一个实现类HashSet为例,简单介绍一下set不重复实现的原理:

    [java] view plain copy
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;

    /**
    * @version 1.0
    * @author Oliver
    * @since 1.0
    */
    publicclass HashSetTest
    {
    //自定义MyString类
    staticclass MyString{
    String value;

        public MyString(String value)  
        {  
            this.value = value;  
        }  
    }  
    publicstaticvoid main(String[] args)  
    {  
        //创建一个HashSet对象  
        Set<Object> set = new HashSet<Object>();  
        //创建连个String对象  
        String s1 = new String("a");  
        String s2 = new String("a");  
        //创建连个MyString对象  
        MyString s3 = new MyString("a");  
        MyString s4 = new MyString("a");  
        //添加元素  
        set.add(s1);  
        set.add(s2);  
        set.add(s3);  
        set.add(s4);  
        //看看对象的equals  
        System.out.println("s1.equals(s2):"+s1.equals(s2));  
        System.out.println("s3.equals(s4):"+s3.equals(s4));  
        //打印几个大小及里面的元素  
        System.out.println("set size:"+set.size());  
        for(Iterator<Object> it=set.iterator();it.hasNext();){  
            System.out.println(it.next());  
        }  
    }  
    

    }

    运行程序,输出结果:
    s1.equals(s2):true

    s3.equals(s4):false

    set size:3

    oliver.examination.part1.HashSetTest$MyString@4f1d0d

    a

    oliver.examination.part1.HashSetTest$MyString@1fc4bec

    也许你已经看出关键来了,没错就是equals方法。这么说还是不恰当,准确的说应该是equals和hashcode方法。

    java.lnag.Object中对hashCode的约定:

    1. 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。

    2. 如果两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。

    3. 如果两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。

    根据第一条,s1和s2返回的hashcode值是一样的。

    在HashSet中,基本的操作都是有HashMap底层实现的,因为HashSet底层是用HashMap存储数据的。当向HashSet中添加元素的时候,首先计算元素的hashcode值,然后用这个(元素的hashcode)%(HashMap集合的大小)+1计算出这个元素的存储位置,如果这个位置位空,就将元素添加进去;如果不为空,则用equals方法比较元素是否相等,相等就不添加,否则找一个空位添加。

    会后,附赠HashSet源码中文注释版,摘自javaeye:http://xifangyuhui.javaeye.com/blog/798796

    [java] view plain copy
    public class HashSet
    extends AbstractSet
    implements Set, Cloneable, java.io.Serializable
    {
    static final long serialVersionUID = -5024744406713321676L;

    // 底层使用HashMap来保存HashSet中所有元素。    
    private transient HashMap<E,Object> map;    
    
    // 定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。    
    private static final Object PRESENT = new Object();    
    
    /**  
     * 默认的无参构造器,构造一个空的HashSet。  
     *   
     * 实际底层会初始化一个空的HashMap,并使用默认初始容量为16和加载因子0.75。  
     */    
    public HashSet() {    
    map = new HashMap<E,Object>();    
    }    
    
    /**  
     * 构造一个包含指定collection中的元素的新set。  
     *  
     * 实际底层使用默认的加载因子0.75和足以包含指定  
     * collection中所有元素的初始容量来创建一个HashMap。  
     * @param c 其中的元素将存放在此set中的collection。  
     */    
    public HashSet(Collection<? extends E> c) {    
    map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));    
    addAll(c);    
    }    
    
    /**  
     * 以指定的initialCapacity和loadFactor构造一个空的HashSet。  
     *  
     * 实际底层以相应的参数构造一个空的HashMap。  
     * @param initialCapacity 初始容量。  
     * @param loadFactor 加载因子。  
     */    
    public HashSet(int initialCapacity, float loadFactor) {    
    map = new HashMap<E,Object>(initialCapacity, loadFactor);    
    }    
    
    /**  
     * 以指定的initialCapacity构造一个空的HashSet。  
     *  
     * 实际底层以相应的参数及加载因子loadFactor为0.75构造一个空的HashMap。  
     * @param initialCapacity 初始容量。  
     */    
    public HashSet(int initialCapacity) {    
    map = new HashMap<E,Object>(initialCapacity);    
    }    
    
    /**  
     * 以指定的initialCapacity和loadFactor构造一个新的空链接哈希集合。  
     * 此构造函数为包访问权限,不对外公开,实际只是是对LinkedHashSet的支持。  
     *  
     * 实际底层会以指定的参数构造一个空LinkedHashMap实例来实现。  
     * @param initialCapacity 初始容量。  
     * @param loadFactor 加载因子。  
     * @param dummy 标记。  
     */    
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {    
    map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);    
    }    
    
    /**  
     * 返回对此set中元素进行迭代的迭代器。返回元素的顺序并不是特定的。  
     *   
     * 底层实际调用底层HashMap的keySet来返回所有的key。  
     * 可见HashSet中的元素,只是存放在了底层HashMap的key上,  
     * value使用一个static final的Object对象标识。  
     * @return 对此set中元素进行迭代的Iterator。  
     */    
    public Iterator<E> iterator() {    
    return map.keySet().iterator();    
    }    
    
    /**  
     * 返回此set中的元素的数量(set的容量)。  
     *  
     * 底层实际调用HashMap的size()方法返回Entry的数量,就得到该Set中元素的个数。  
     * @return 此set中的元素的数量(set的容量)。  
     */    
    public int size() {    
    return map.size();    
    }    
    
    /**  
     * 如果此set不包含任何元素,则返回true。  
     *  
     * 底层实际调用HashMap的isEmpty()判断该HashSet是否为空。  
     * @return 如果此set不包含任何元素,则返回true。  
     */    
    public boolean isEmpty() {    
    return map.isEmpty();    
    }    
    
    /**  
     * 如果此set包含指定元素,则返回true。  
     * 更确切地讲,当且仅当此set包含一个满足(o==null ? e==null : o.equals(e))  
     * 的e元素时,返回true。  
     *  
     * 底层实际调用HashMap的containsKey判断是否包含指定key。  
     * @param o 在此set中的存在已得到测试的元素。  
     * @return 如果此set包含指定元素,则返回true。  
     */    
    public boolean contains(Object o) {    
    return map.containsKey(o);    
    }    
    
    /**  
     * 如果此set中尚未包含指定元素,则添加指定元素。  
     * 更确切地讲,如果此 set 没有包含满足(e==null ? e2==null : e.equals(e2))  
     * 的元素e2,则向此set 添加指定的元素e。  
     * 如果此set已包含该元素,则该调用不更改set并返回false。  
     *  
     * 底层实际将将该元素作为key放入HashMap。  
     * 由于HashMap的put()方法添加key-value对时,当新放入HashMap的Entry中key  
     * 与集合中原有Entry的key相同(hashCode()返回值相等,通过equals比较也返回true),  
     * 新添加的Entry的value会将覆盖原来Entry的value,但key不会有任何改变,  
     * 因此如果向HashSet中添加一个已经存在的元素时,新添加的集合元素将不会被放入HashMap中,  
     * 原来的元素也不会有任何改变,这也就满足了Set中元素不重复的特性。  
     * @param e 将添加到此set中的元素。  
     * @return 如果此set尚未包含指定元素,则返回true。  
     */    
    public boolean add(E e) {    
    return map.put(e, PRESENT)==null;    
    }    
    
    /**  
     * 如果指定元素存在于此set中,则将其移除。  
     * 更确切地讲,如果此set包含一个满足(o==null ? e==null : o.equals(e))的元素e,  
     * 则将其移除。如果此set已包含该元素,则返回true  
     * (或者:如果此set因调用而发生更改,则返回true)。(一旦调用返回,则此set不再包含该元素)。  
     *  
     * 底层实际调用HashMap的remove方法删除指定Entry。  
     * @param o 如果存在于此set中则需要将其移除的对象。  
     * @return 如果set包含指定元素,则返回true。  
     */    
    public boolean remove(Object o) {    
    return map.remove(o)==PRESENT;    
    }    
    
    /**  
     * 从此set中移除所有元素。此调用返回后,该set将为空。  
     *  
     * 底层实际调用HashMap的clear方法清空Entry中所有元素。  
     */    
    public void clear() {    
    map.clear();    
    }    
    
    /**   
     * 返回此HashSet实例的浅表副本:并没有复制这些元素本身。   
     * 
    
    展开全文
  • Set集合实现元素不重复原理

    千次阅读 2015-10-04 11:39:54
    众所周知,set内容不重复。以hashSet为例,会使用对象的hashCode()与equals()来判断存入的对象是否相同。详解收集过程如下。

    众所周知,set内容不重复。以hashSet为例,会使用对象的hashCode()与equals()来判断存入的对象是否相同。流程如下:
    要存入元素,内存中开设空间,每个空间都会有对应的Hash Code,这些空间成为哈希桶(Hash Bucket)。
    这里写图片描述
    对想要存入HashSet回调用对象的hashCode()获取对应的哈希值,并尝试放入对应的哈希桶中,如果哈希桶中没有对象,则直接放入,如果有,会再调用对象的equals()比较。
    这里写图片描述
    桶中的对象调用equals()与要传入的对象进行比较,若比较结果为false,则表示两个对象非重复,可以存入,若结果为true,表示两个对象相同,不可存入。

    例:
    学生类(Student),为了防止收集重复对象,在Student类中复写hashCode()和equals():

     class Studen{
        private String name ;//姓名
        private int age;//年龄
    
        public int hashCode(){
            return name.hashCode()+age*33;
        }       
        public boolean equals(Object obj){
            if(!(obj instanceof Student))
                throw new ClassCastException("类型不匹配");
            Student s=(Student) obj;
            return this.name.equals(s.name) &&this.age==s.age;          
        }
    }

    如果之后出现重复对象想要被收集时,要存入对象便会和已存在容器内的对象比较,如果相同则不能再存入。

    展开全文
  • 刚开始写Java集合类中的Set的时候,只知道要是让存入的元素不重复,必须实现hashCode和equals方法,但是当时不知道原因,最近看到一篇文章就是介绍这个的,拿出来分享一下点击打开链接
    刚开始写Java集合类中的Set的时候,只知道要是让存入的元素不重复,必须实现hashCode和equals方法,但是当时不知道原因,最近看到一篇文章就是介绍这个的,拿出来分享一下
    点击打开链接
    展开全文
  • 1.redis是单进程、单线程运行得,所以得请求会被放到队列中串行化。 2.set集合采用哈系表实现

    1.redis是单进程、单线程运行得,所以得请求会被放到队列中串行化。

    2.set集合采用哈系表实现

    展开全文
  • Set 怎么保证不重复

    千次阅读 2017-07-04 17:21:30
    因为map中的key是允许重复的,所以set中的元素重复。HashMap的往里放元素的源码!!! public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()...
  • //添加一个set集合 Set set=new HashSet(); Animal animal1=new Animal("dongwu",2); Animal animal2=new Animal("dongwu",2); Animal animal3=new Animal("dongwu",2); //s...
  •  如果相等,认为两个对象也相等,完毕  如果相等,转入2) (这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的。后面会重点讲...
  • List是有序且重复的,Set是无序不重复的。这里说的顺序有两个概念,一是按添加的顺序排列,二是按自然顺序a-z排列。Set并不是无序的,传统说的Set无序是指HashSet,它不能保证元素的添加顺序,更不能保证自然顺序,而...
  • Java中list去重(用set元素不重复性)

    万次阅读 2018-03-12 23:08:54
     在网上找了几种方法利用HashSet里面的元素重复利用list里面contains方法比较是否存在去重首页我试验了第一种方法public static void main(String args[]){ ArrayList&lt;Integer&gt; arra...
  • Set如何实现“没有重复元素”

    千次阅读 2009-10-18 23:19:00
    这篇文章主要论述了Set是如何实现"没有重复元素"(no duplicate elements)的,以及阐述了什么是“重复”(duplicate),是相同的地址空间?是equals的返回值为true?是compareTo的返回值为0 ?还是有相同的hashCode...
  • 为什么Set集合是无序和不重复的?

    千次阅读 2019-05-22 22:41:33
    ###Set集合元素为什么不重复,是如何实现不重复的? 对于基本数据类型特征的数据,Set集合可以直接比较是否相等,相等就去掉重复。 对于引用数据类型的数据,Set集合将会按照如下流程判断是否重复: Set集合每次...
  • javaSE Set集合,元素无序不重复

    千次阅读 2018-06-11 22:16:00
    Collection(集合):容器,用于存放对象(引用类型。... 查看Set(集):元素无序,重复 (没有索引)。 遍历只能用Iterator迭代器和增强for, 能使用普通for遍历。ArrayList(数组列表): 查询快,增删慢。 查看LinkedLis...
  • Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍   要求: 今天要测试上千条数据,且每条数据要求执行多次,(模拟多用户多次抽奖) 1.用户id有175个,且没有任何排序规则; 2.要求175个用户都去请求...
  • Set实现数组去重

    千次阅读 2019-10-04 03:01:18
    ES6 提供了新的数据结构 Set 它类似于数组,但是成员的值都...使用Set实现数组去重要简单很多。 第一种数组去重方法(使用Array.from): let arr = [12,43,23,43,68,12]; let item = new Set(arr); co...
  • 这里写自定义目录标题Set集合是如何保证元素重复总结 Set集合是如何保证元素重复 在使用集合的时候,会经常用到Set集合,Set集合的特点如下: 1,元素无序 2,元素重复 那么Set集合底层是如何保证元素...
  • 前一篇博文Java 集合体系详解——List体系有序集合总结了下List体系集合的用法,这一篇主要总结Set体系集合的相关知识点,Set集合体系存储特点是元素是无序的(存入和取出的顺序一定一致的),元素可以重复。...
  • 【用set集合去重复数据,重写equals还是成功的问题解决思路在文章最后】 需求描述: 因业务需要,通过复杂的代码逻辑从数据库取出数据放入List集合中,涉及多次从访问数据库取出数据放入List集合中,其中会取到...
  • 我所知道的自定义compare方法似乎是提供两个放进去的东西的先后顺序关系的比较,如何实现用自己定义的方法实现set内成员满足我所定义的不重复?然后我知道好像Java里可以通过重写equals函数,c++行吗?
  • Set解决重复数据问题

    千次阅读 2019-10-14 09:32:49
    HashSet实现set接口,实际上是由hashMap实现的,所以保证遍历顺序,并且允许使用null,时间复杂度和hashMap一样,为O(1),超过O(n)。 set不允许重复的元素,如果set已经有重复的元素,会返回false。 案例,给定一...
  • set为什么能存储重复

    千次阅读 2018-11-24 16:42:52
    set的两个主要实现类,TreeSet和HashSet,...map每次put如果key值存在,返回的是null,key值如果存在,则返回之前key的oldValue,这样与null做对比的时候返回的就是false,在set层面就是插入重复值失败了  ...
  • 我们都知道Set集合不能包含重复数据,那么Set是怎么保证数据不重复,怎么比较要加入的数据到底和已加入的数据以及不同数据的定义是什么? public class HashSetDemo {public static void main(String[] args) {// ...
  • List接口实现的存储是有序可重复的,Set接口是无序不重复的,不能用下标定位数据 结合他们之间的优缺点和数据量,在不考虑性能的情况下,笔者写了有序不重复的集合 总体是基于LinkedList实现的,重写其add
  • Go语言实现set -使用切片实现

    千次阅读 2018-11-21 12:26:13
    网上很多都是使用了自带的map来实现的一个不重复Set,使用的是map的key不重复,value就是随便了,我觉得可以自己造轮子了, 就自己实现了一个实现了一个,当然.第一个版本是不考虑线程安全等等.....就做一个简单的实现...
  • 从该串中取出3个不重复的字符,求所有的取法。 取出的字符,要求按字母升序排列成一个串。 不同的取法输出顺序可以不考虑。 例如: 输入: abc 则输出: abc 输入: abcd 则输出: abc abd acd bcd 输入: abcaa 则...
  • C++set实现

    千次阅读 2019-10-17 10:36:31
    set提供快速的查找功能,其特性是:...set使用rb-tree作为底层容器,rb-tree提供了所有set需要的操作,set不允许键值重复,使用rb-tree的insert_unique来插入元素 代码实现:https://github.com/inmail/mySTL/blob/...
  • Set集合继承于Collection集合,set中即能包含重复数据又是无序的,set集合之所以包含重复数据的原因在于:  因为当我们往一个空的Set集合中加入数据时,第一次加入的数据会直接加入到集合中,从第一个往后所有...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 606,296
精华内容 242,518
关键字:

set如何实现不重复