search

Home  >  Q&A  >  body text

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

高洛峰高洛峰2803 days ago837

reply all(3)I'll reply

  • 迷茫

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

    I checked the source code, and I think there is an article here about Hash of HashSet. 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. First look at the process of adding elements
          //HashSet code
    • rrreee
    Add new elements to the map maintained internally by HashSet
    //HashMap code🎜 rrreee 🎜It can be seen that Element will be hashed, so if you add Foo(1), this link will be indispensable in the process of saving to HashSet of. 🎜
      1. 🎜Let’s look at the comparison
        //HashSet code🎜🎜🎜🎜🎜 rrreee 🎜//HashMap code🎜 rrreee rrreee
          1. 🎜Conclusion
            When inserting a HashSet container, the elements must be hashed. When determining whether the container contains an element, the elements must also be hashed. What they compare is the hash value of the elements. 🎜🎜🎜🎜🎜

            reply
            0
  • ringa_lee

    ringa_lee2017-04-17 16:56:09

    equals method, but it is worth noting that the second floor is talking about the equals method under String, because the equals method of String has been rewritten. If the subject wants to compare general Objects through the contains method, it still has to be compared with String Rewrite the equals method in the same way to determine what rules

    reply
    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;
    }
    

    This is AbstractCollection的实现, AbstractList, AbstractSetimplemented using this as the parent class.

    reply
    0
  • Cancelreply