java - 关于list集合和set集合的问题请大神指导一下
高洛峰
高洛峰 2017-04-17 16:54:09
0
3
769
高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

reply all (3)
迷茫

我查了下源码,我觉得HashSetHash这里有文章。

  • 1.首先看添加元素的过程
    //HashSet代码

/** * Adds the specified element to this set if it is not already present. * More formally, adds the specified element e to this set if * this set contains no element e2 such that * (e==null ? e2==null : e.equals(e2)). * If this set already contains the element, the call leaves the set * unchanged and returns false. * * @param e element to be added to this set * @return true if this set did not already contain the specified * element */ public boolean add(E e) { return map.put(e, PRESENT)==null; }

HashSet内部维护的map添加新元素
//HashMap代码

/** * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for the key, the old * value is replaced. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with key, or * null if there was no mapping for key. * (A null return can also indicate that the map * previously associated null with key.) */ public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }

可以看出会对Element做哈希,所以如果添加Foo(1)的话,保存到HashSet过程中也少不了这个环节的。

    1. 再来看比较的情况
      //HashSet代码

/** * Returns true if this set contains the specified element. * More formally, returns true if and only if this set * contains an element e such that * (o==null ? e==null : o.equals(e)). * * @param o element whose presence in this set is to be tested * @return true if this set contains the specified element */ public boolean contains(Object o) { return map.containsKey(o); }

//HashMap代码

/** * Returns true if this map contains a mapping for the * specified key. * * @param key The key whose presence in this map is to be tested * @return true if this map contains a mapping for the specified * key. */ public boolean containsKey(Object key) { return getEntry(key) != null; }
/** * Returns the entry associated with the specified key in the * HashMap. Returns null if the HashMap contains no mapping * for the key. */ final Entry getEntry(Object key) { if (size == 0) { return null; } int hash = (key == null) ? 0 : hash(key); for (Entry e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e; } return null; }
    1. 结论
      插入HashSet容器时对元素做哈希,判断容器是否含有某个元素时也要对元素做哈希,他们比较的是元素的哈希值。

    左手右手慢动作

    equals的方法,但是值得注意的是二楼说的是String下的equals方法,因为String的equals方法是重写过的,如果题主希望通过contains方法对于一般Object的比较的话,还是得和String一样重写equals方法,确定何种规则

      PHPzhong
      public boolean contains(Object o) { Iterator it = iterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return true; } else { while (it.hasNext()) if (o.equals(it.next())) return true; } return false; }

      这个是AbstractCollection的实现,AbstractList,AbstractSet都是以此为父类实现的.

        Latest Downloads
        More>
        Web Effects
        Website Source Code
        Website Materials
        Front End Template
        About us Disclaimer Sitemap
        php.cn:Public welfare online PHP training,Help PHP learners grow quickly!