精华内容
下载资源
问答
  • set集合为什么不能存放重复数据

    千次阅读 2019-07-04 15:40:54
    set集合为什么不能存放重复数据:            a)加入Set里面的元素必须定义equals()方法以确保对象的唯一性。        ...

    set集合为什么不能存放重复数据:

               a)加入Set里面的元素必须定义equals()方法以确保对象的唯一性。

               b)set中插入数据时,先比较hashCode:

                          i.如果hashCode相同才会比较equals,equals相同,则两个对象相同,不能插入,equals不同,可以插入;

                          ii.如果hashCode不同,就直接插入了,两个对象hashCode不相等,他们equals一定是false。


    展开全文
  • Set中的元素为什么不允许重复

    万次阅读 2015-12-16 18:44:37
      为了弄清楚这个问题 , 我又看了一遍 Collection 部分 , 并且看了些其中的源码 , 觉得对其中的实现又明白了一点 ...Set 接口我们提供了一个 add() 方法,以让我们添加元素。所以我们看一下在其实现类

     版权所有,转载请声明出处 zhyiwww@163.com

     

    为了弄清楚这个问题 , 我又看了一遍 Collection 部分 , 并且看了些其中的源码 , 觉得对其中的实现又明白了一点 , 现在说出来和大家共享 .

    我们先看一下 Set 类的关系图: 

    hashset.png 
    现在我们就从 Set 说起。

    Set 接口为我们提供了一个 add() 方法,以让我们添加元素。所以我们看一下在其实现类 HashSet 中是如何实现的呢?

    我们看 HashSet 中的 add() 方法实现;

        public boolean add( E o ) {

                  return  map.put(o, PRESENT)==null;

    }

    你可能回问怎么回出来 map 了呢?

    Map 又是一个什么变量呢?

    我们来看 map 是在在哪定义的。原来,在 HashSet 中定义了这样的两个变量:

        private transient HashMap<E,Object> map;

        private static final Object PRESENT = new Object();

    我们再看一下上面的 add() 方法。

    map.put(o, PRESENT)==null

    实际执行的是 map 的方法,并且我们添加的对象是 map 中的 key,value 是执行的同一个对象PRESENT.

    因为map中的key是不允许重复的,所以set中的元素不能重复。

     

    下面我们再看一下, map 又是如何保证其 key 不重复的呢?

     hashmap.png

    现在我们看一下 map 中的 put() 方法的实现:

    HashMap 实现了 map ,在 HashMap 中是这样实现的:

        public V put(K key, V value) {

          K k = maskNull(key);

            int hash = hash(k);

            int i = indexFor(hash, table.length);

            for (Entry<K,V> e = table[i]; e != null; e = e.next) {

                if (e.hash == hash && eq(k, e.key)) {

                    V oldValue = e.value;

                    e.value = value;

                    e.recordAccess(this);

                    return oldValue;

                }

            }

     

            modCount++;

            addEntry(hash, k, value, i);

            return null;

        }

    我们我们按照方法的执行一步一步的来看一下,其实现的过程。

    K k = maskNull(key);

    这一步是要判断当前的要添加的对象的 key 是否为空,如果为空的话,那么就生成一个新的对象作为其 key 。实现如下:

        static final Object NULL_KEY = new Object();

         * Returns internal representation for key. Use NULL_KEY if key is null.

        static <T> T maskNull(T key) {

            return key == null ? (T)NULL_KEY : key;

        }

    之后

    int hash = hash(k);

    我们看一下 hash() 方法的实现:

        static int hash(Object x) {

            int h = x.hashCode();

            h += ~(h << 9);

            h ^=  (h >>> 14);

            h +=  (h << 4);

            h ^=  (h >>> 10);

            return h;

        }

    这一步其实是要得到当前要添加对象的 hashcode, 方法中,首先通过int h = x.hashCode() 取得了当前的要添加对象的 hashcode, 然后

            h += ~(h << 9);

            h ^=  (h >>> 14);

            h +=  (h << 4);

            h ^=  (h >>> 10);

    生成一个新的 hashcode.

    接着执行的是

    (从此处开始,我理解的比较肤浅,请看到此出的朋友多多指点)

    int i = indexFor(hash, table.length);

    这个方法是要 Returns index for hash code h.

        static int indexFor(int h, int length) {

            return h & (length-1);

        }

          下面就要根据 hashmap 中的元素逐个的比较,看是否相同,如果不同就回添加一个新的元素。是通过循环判断来实现的。

            for (Entry<K,V> e = table[i]; e != null; e = e.next) {

                if (e.hash == hash && eq(k, e.key)) {

                    V oldValue = e.value;

                    e.value = value;

                    e.recordAccess(this);

    这句我的理解是:在内存中的可以访问元素又多了一个。也就是说,添加之后,可以通过hashmap来访问此元素了。

                    return oldValue;

                }

            }

    通过循环判断是否有完全相同的对象,包括 hashcode 和 value 值。如果已经存在就返回其值,如果不存在就执行一下操作。

            modCount++;

            addEntry(hash, k, value, i);

            return null;

    对象不存在,首先修改 hashmap 的修改次数,即 modCount 加 1. 然后将对象添加到数组中。

        void addEntry(int hash, K key, V value, int bucketIndex) {

          Entry<K,V> e = table[bucketIndex];

            table[bucketIndex] = new Entry<K,V>(hash, key, value, e);

            if (size++ >= threshold)

                resize(2 * table.length);

    }

    仍然是数组,我们来看一下 , 在 hashmap 中用来存放对象的数组的定义:

        transient Entry[] table;

    至此,我想大家也许应该明白了,为什么在 set 中是不允许存放重复值的。

    通过才的分析,我们可以看到, map 的一些特征:

    1.       在 map 中也是不能存放完全相同的元素的

    2.       如果你存入的对象的 key 值已经存在的话,那么新的 value 将会取代老的 value 值,但是并不会添加新的元素进去。

    我们可以通过一个测试程序来证明这一点:

      public void mapTest() {

        Map m = new HashMap();

        /**

         * we  can  put  the  int  1 and the  value  1  into  the  map

         * but  we  cannot  get  the  1 as  int  from the map

         * why ?

         * we  only  get  the  1  as  integer  from  the map,

         * so  we  only  get the object  from the map,if we  put the  value into

         * the map,we  will get one  instance of  the wrapper  of  that

         */

        m.put(1, 1);

        //int i = m.get(1);

        Integer i = (Integer) m.get(1);

        System.out.println(i);

     

        m.put(1, 1);

        m.put(1, 1);

        System.out.println("map   :    " + m);

        System.out.println("map  size    :   " + m.size());

        m.put(1, 2);

        System.out.println("map   :    " + m);

        System.out.println("map  size    :   " + m.size());

      }

    运行的结果是:

    map   :    {1=1}

    map  size    :   1

    map   :    {1=2}

    map  size    :   1

    希望此文能大家有所帮助。

    展开全文
  • set为什么不能存储重复

    千次阅读 2018-11-24 16:42:52
    set的两个主要实现类,TreeSet和HashSet,...map每次put如果key值存在,返回的是null,key值如果存在,则返回之前key的oldValue,这样与null做对比的时候返回的就是false,在set层面就是插入重复值失败了  ...

     

    set的两个主要实现类,TreeSet和HashSet,底层存储结构都是用的map,而且是将set需要存储的值放在map的key里的,PRESENT是一个空的object对象。

    map每次put如果key值不存在,返回的是null,key值如果存在,则返回之前key的oldValue,这样与null做对比的时候返回的就是false,在set层面就是插入重复值失败了

     

    展开全文
  • set中的元素不能相等重复的,这一点我知道,那么怎样才是(重复呢? 是hashcode相等?是地址相同?是元素的equal返回true? 猜测:先判断是不是同一个引用(地址),再判断equal 我自己做了...
  • Set是Collection容器的一个子接口,它允许出现重复元素,当然也只允许有一个null对象。 2、如何来区分重复与否呢?(how) “用iterator()方法来区分重复与否”,这是在网上流传的答案,个人认为这是个错误...

    1、什么是Set?(what)

         Set是Collection容器的一个子接口,它不允许出现重复元素,当然也只允许有一个null对象。

     

    2、如何来区分重复与否呢?(how)

     

         “ 用 iterator() 方法来区分重复与否 ”,这是在网上流传的答案,个人认为这是个错误的答案。API中写的很明白:“set 不包含满足

    e1.equals(e2) 的元素对 e1 和 e2 ”,由此可见回答使用equals()区分更合适。

     

    3、为什么用equals()而不用==来区分?(why)

     

         应该从它俩的区别谈起,==是用来判断两者是否是同一对象(同一事物),而equals是用来判断是否引用同一个对象。再看一下Set里面存的是

    对象,还是对象的引用。根据java的存储机制可知,set里面存放的是对象的引用,所以当两个元素只要满足了equals()时就已经指向同一个对象,

    也就出现了重复元素。所以应该用equals()来判断。

    展开全文
  • Set集合允许存储重复元素原理

    千次阅读 2020-06-22 20:46:38
    Set集合允许存储重复元素原理 package com.Set; import java.util.HashSet; /* Set集合允许存储重复元素原理 */ public class Demo02HashSetSaveString { public static void main(String[] args) { //创建...
  • Python去除列表中的重复元素

    万次阅读 多人点赞 2019-04-30 23:21:39
    1.使用set去除重复元素 list1 = [1, 2, 5, 6, 7, 4, 8, 2, 7, 9, 4, 6, 3] list2 = list(set(list1)) print(list2) 输出结果如下: 会改变原列表元素的顺序。 [1, 2, 3, 4, 5, 6, 7, 8, 9] 2.for循环语句 list1 = ...
  • java为什么吗list允许存储重复元素,而set不允许存储重复元素
  • Set集合是如何保证元素不重复

    千次阅读 2019-12-14 17:10:06
    这里写自定义目录标题Set集合是如何保证元素不重复总结 Set集合是如何保证元素不重复 在使用集合的时候,会经常用到Set集合,Set集合的特点如下: 1,元素无序 2,元素不重复 那么Set集合底层是如何保证元素...
  • 为什么Set集合是无序和不重复的?

    千次阅读 2019-05-22 22:41:33
    ###Set集合元素为什么不重复,是如何实现不重复的? 对于基本数据类型特征的数据,Set集合可以直接比较是否相等,相等就去掉重复。 对于引用数据类型的数据,Set集合将会按照如下流程判断是否重复: Set集合每次...
  • Set里的元素不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? 1、什么Set?(what) Set是Collection容器的一个子接口,它允许出现重复元素,当然也只允许有一个null对象。 2、...
  • Set里面的元素是不能重复的,,元素重复与否是使用equals()方法来进行判断的。。  equals()和==方法决定引用值是否指向同一个对象equals()在类中被覆盖,的是当两个分离的对象的内容和类型相匹配的话,返回真值...
  • java:Set可以插入重复元素

    千次阅读 2020-10-23 19:12:01
    Set<List<Integer>> res1 = new HashSet<>(); res1.add(new ArrayList<>()); res1.add(new ArrayList<>(Arrays.asList(1))); Set<List<Integer>> ...
  • Set集合重复元素的判断

    千次阅读 2018-06-14 08:44:06
    更重要的是Set集合不能放置重复元素.她是怎么判断的呢?那么,我们首先要让对象具有比较性 一,存储的自定义对象实现接口 Comparable 复写public int compareTo()方法. 返回0表示二者相等. 如...
  • C++ std::set 出现重复元素

    千次阅读 2021-03-13 23:46:58
    如题,今天自定义了一个set的排序函数,重新构造了set,往里插入元素的时候居然出现了重复元素! 首先set的比较函数含义是按照元素的出现频率比较,高频率的大于低频率,如果二者频率相等,则数值小的大于数值大的...
  • Set集合如何判断重复元素

    千次阅读 2019-04-20 15:06:00
    1.TreeSet子类是利用Comparable接口来实现重复元素的判断,但是Set集合的整体特征就是允许保存重复元素。...2.HashSet判断元素重复是利用Object类中的方法实现的: -|对象编码:public int hashCode(); -|对象...
  • javaSE Set集合,元素无序不重复

    千次阅读 2018-06-11 22:16:00
    Collection(集合):容器,用于存放对象(引用类型。... 查看Set(集):元素无序,重复 (没有索引)。 遍历只能用Iterator迭代器和增强for, 不能使用普通for遍历。ArrayList(数组列表): 查询快,增删慢。 查看LinkedLis...
  • 要点:set集合存储元素不重复元素前提:存储的元素必须重写hashCode方法和equals方法。 example: //创建HashSet集合对象 HashSet<String> set = new HashSet<>(); String s1 = new String( ...
  • Java中list去重(用set元素不重复性)

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

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

    千次阅读 2019-05-04 13:21:35
    java 集合 Set 插入重复元素
  • Java中利用Set判断List集合中是否有重复元素

    万次阅读 多人点赞 2018-12-05 20:05:36
    我们需要找出重复元素,我们只需要返回一个Boolean类型就可以了 如果使用循环遍历的方式,将会消耗大量的性能 我们只需要将List集合转化为Set集合,再进行比较就可以实现了: 代码如下: package com.test; ...
  • Set是无序的,传统说的Set无序是指HashSet,它不能保证元素的添加顺序,更不能保证自然顺序,而Set的其他实现类是可以实现这两种顺序的。 保证元素添加的顺序,保证元素自然的顺序,可重复:List 保证元素...
  • STL--set介绍及set的使用

    万次阅读 多人点赞 2018-08-23 11:52:01
    1.set介绍 (1)set是STL中一个很有用的容器,用来存储同一种数据类型的数据结构(可以称之...(4)set中数元素的值并不能直接被改变。 2.set的底层 (1)set的底层是红黑树,是红黑树里面K的模型; K模型:...
  • 去除Set集合中的重复元素

    千次阅读 2019-01-26 15:44:23
    去除 Set 集合的重复元素的方法与 equals(),hashCode()方法有关 class Person{ String name; int age; public String toString(){ return name+"..."+age; } } public class test1{ publi...
  • java中set集合如何去除重复元素

    万次阅读 2017-07-25 19:12:11
    set集合是可以重复元素集合; 用set集合添加一个学生对象元素时:import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set;public class ...
  • 如何在Set集合中添加重复元素

    千次阅读 2020-03-22 00:16:43
    Set集合元素重复比较    当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有...
  • Set<Worker> set = new HashSet(); set.add(new Worker("tom", 18, 2000)); set.add(new Worker("tom", 18, 2000)); set.add(new Worker("jerry", 18, 2000)); for (Worker worker : set) { System....
  • c++中容器set的去除重复元素排序

    千次阅读 2018-08-22 15:28:05
    两者不同在于前者允许元素重复,而后者允许。 1) 不能直接改变元素值,因为那样会打乱原本正确的顺序,要改变元素值必须先删除旧元素,则插入新元素 2) 提供直接存取元素的任何操作函数,只能通过迭代器进行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 378,401
精华内容 151,360
关键字:

set元素为什么不能重复