首頁  >  問答  >  主體

java - 关于list集合和set集合的问题请大神指导一下

高洛峰高洛峰2762 天前809

全部回覆(3)我來回復

  • 迷茫

    迷茫2017-04-17 16:56:09

    我查了下源碼,我覺得HashSetHash這裡有文章。 HashSetHash这里有文章。

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

        /**
         * Adds the specified element to this set if it is not already present.
         * More formally, adds the specified element <tt>e</tt> to this set if
         * this set contains no element <tt>e2</tt> such that
         * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
         * If this set already contains the element, the call leaves the set
         * unchanged and returns <tt>false</tt>.
         *
         * @param e element to be added to this set
         * @return <tt>true</tt> 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 <tt>key</tt>, or
         *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
         *         (A <tt>null</tt> return can also indicate that the map
         *         previously associated <tt>null</tt> with <tt>key</tt>.)
         */
        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<K,V> 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 <tt>true</tt> if this set contains the specified element.
         * More formally, returns <tt>true</tt> if and only if this set
         * contains an element <tt>e</tt> such that
         * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
         *
         * @param o element whose presence in this set is to be tested
         * @return <tt>true</tt> if this set contains the specified element
         */
        public boolean contains(Object o) {
            return map.containsKey(o);
        }

    //HashMap代码

        /**
         * Returns <tt>true</tt> if this map contains a mapping for the
         * specified key.
         *
         * @param   key   The key whose presence in this map is to be tested
         * @return <tt>true</tt> 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<K,V> getEntry(Object key) {
            if (size == 0) {
                return null;
            }
    
            int hash = (key == null) ? 0 : hash(key);
            for (Entry<K,V> 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

        • 1.首先看加入元素的過程
          //HashSet程式碼
    • rrreee
    HashSet內部維護的map新增元素
    //HashMap程式碼🎜 rrreee 🎜可以看出會對Element做哈希,所以如果加入Foo(1)的話,儲存到HashSet過程中也少不了這個環節的。 🎜
      1. 🎜再來看比較的情況
        //HashSet程式碼🎜🎜🎜🎜🎜 rrreee 🎜//HashMap程式碼🎜 rrreee rrreee
          1. 🎜結論
            插入HashSet容器時對元素做哈希,判斷容器是否含有某個元素時也要對元素做哈希,他們比較的是元素的雜湊值。 🎜🎜🎜🎜🎜

            回覆
            0
  • ringa_lee

    ringa_lee2017-04-17 16:56:09

    equals的方法,但是值得注意的是二樓說的是String下的equals方法,因為String的equals方法是重寫過的,如果題主希望透過contains方法對於一般Object的比較的話,還是得和String一樣重寫equals方法,確定何種規則

    回覆
    0
  • PHPz

    PHPz2017-04-17 16:56:09

        public boolean contains(Object o) {
        Iterator<E> 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都是以此為父類實現的.

    回覆
    0
  • 取消回覆