HashMap and ArrayList how to enlarge

Source: Internet
Author: User
Tags prev

The longest in Java is the collection of HashMap and ArrayList two, which describes how they are scaled up. HashMap Initialization of

1. Direct initialization

/**
     * Constructs a empty <tt>HashMap</tt> with the default initial capacity
     * () and the default Lo Ad factor (0.75).
     * * Public
    HashMap () {This
        (default_initial_capacity, default_load_factor);
}
2. Set parameter initialization
/** * Constructs a empty <tt>HashMap</tt> with the specified initial * capacity and load factor. * * @param initialcapacity The initial capacity * @param loadfactor the load factor * @throws Il Legalargumentexception If the initial capacity is negative * or the load factor is nonpositive/PU Blic HashMap (int initialcapacity, float loadfactor) {if (Initialcapacity < 0) throw new Illegalarg
        Umentexception ("Illegal initial capacity:" + initialcapacity);
        if (initialcapacity > maximum_capacity) initialcapacity = maximum_capacity; if (loadfactor <= 0 | |
                                               Float.isnan (Loadfactor)) throw new IllegalArgumentException ("Illegal load factor:" +

        Loadfactor);
        This.loadfactor = Loadfactor;
        threshold = initialcapacity;
Init ();
 }
3. Initialize with map
/**
     * Constructs a new <tt>HashMap</tt> with the same mappings as the
     * specified <TT>MAP</TT ".  The <tt>HashMap</tt> is created with
     * default load factor (0.75) and a initial capacity sufficient to
  * hold the mappings in the specified <tt>map</tt>.
     *
     * @param   m The map whose mappings are to is placed in this map
     * @throws  nullpointerexception if the SPE  Cified map is null
    /public HashMap (map<? extends K,. Extends v> m) {This (Math.max (
        int) (M.size () /default_load_factor) + 1,
                      default_initial_capacity), default_load_factor);
        Inflatetable (this.threshold);

        Putallforcreate (m);
    }
, the load factor is 0.75.

Note: m.size ()/Default_load_facto, and then look at the following code:

/**
 * Inflates the table.
 *
 private void inflatetable (int tosize) {
 //Find a power of 2 >= tosize
 int capacity = Roun      DUPTOPOWEROF2 (tosize);

 threshold = (int) math.min (capacity * Loadfactor, maximum_capacity + 1);
 Table = new Entry[capacity];
 Inithashseedasneeded (capacity);
 }
So the number of buckets is initcapcity, and the threshold is capacity * this.loadfactor. Indicates that the threshold value is only bucket number *loadfactor, so the pain is not full. At the same time, look at the following add that the number of elements in the addition process, will not be redundant bucket number *loadfactor.

ROUNDUPTOPOWEROF2 is actually the integer power that takes the first 2 that is larger than this value (initcapcity).

The code above is also used in the Put method. Add

/** * Associates The specified value with the specified key into 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 associated * @param value value of * associated with The specified key * @return The previous value associated with <tt>key</tt>, or * <tt&gt
     ;null</tt> If there is no mapping for <tt>key</tt>. * (A <tt>null</tt> return can also indicate the map * previously associated &LT;TT&G
     T;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;
 }
The final addition is the call to the addentry operation.

/**
     * Adds A new entry with the specified key, value and hash code to
     * specified bucket.  It is the responsibility of this
     * method to resize the table if appropriate.
     *
     * Subclass overrides this to alter the behavior.
     */
    void addentry (int hash, K key, V value, int bucketindex) {
        if (size >= threshold) && (null!= table [Bucketindex]) {
            Resize (2 * table.length);
            hash = (null!= key)? Hash (key): 0;
            Bucketindex = Indexfor (hash, table.length);
        }

        Createentry (hash, key, value, Bucketindex);
    
As you can see here, HashMap doubles the number of buckets that are hashmap when the number of elements (not the number of buckets) reaches the threshold.

/** * Rehashes The contents of this map to a new array with a * larger capacity.
     This are called automatically when the * number of keys in this map reaches its threshold. * * If current capacity are maximum_capacity, this method does not * Resize the map, but sets threshold to Intege
     R.max_value.
     * This has the effect of preventing future calls.
     * * @param newcapacity The new capacity, must is a power of two; * Must be greater than current capacity unless current * capacity-maximum_capacity (in which case VA
     Lue * is irrelevant).
        */void Resize (int newcapacity) {entry[] oldtable = table;
        int oldcapacity = Oldtable.length;
            if (oldcapacity = = maximum_capacity) {threshold = Integer.max_value;
        Return
        } entry[] newtable = new Entry[newcapacity];
        Transfer (newtable, inithashseedasneeded (newcapacity)); Table = NEwtable;
    threshold = (int) math.min (newcapacity * loadfactor, maximum_capacity + 1);
 }
void Transfer (entry[] Paramarrayofentry, Boolean paramboolean) {
	int i = paramarrayofentry.length;
	entry[] Arrayofentry = this.table;
	int j = arrayofentry.length;
	for (int k = 0; k < J; ++k) {
		Entry localentry;
		for (Object localobject = arrayofentry[k]; null!= localobject; localobject = localentry) {
			localentry = ((Entry) Loca LOBject). Next;
			if (Paramboolean)
				((Entry) localobject). Hash = ((Null = = ((Entry) localobject). Key)? 0
						: Hash (((Entry) Localobje CT). key);
			int L = indexfor (((Entry) localobject). hash, i);
			((Entry) localobject). Next = Paramarrayofentry[l];
			Paramarrayofentry[l] = localobject;
		}
	}
It can be seen that after the expansion, HashMap will again insert elements into the new bucket according to the hash algorithm, so write code, to avoid this situation, if you can know beforehand or estimate the size of the HashMap, allocate enough space.

void Createentry (int paramInt1, K paramk, V paramv, int paramInt2) {
	Entry localentry = This.table[paramint2];
	This.table[paramint2] = new Entry (paramInt1, Paramk, PARAMV, localentry);
	This.size + 1;
}

Here's a look at the hash algorithm.

/**
     * Retrieve Object hash code and applies a supplemental hash function
     to the * result hash, which defends again St poor quality hash functions.  This
     is * critical because HASHMAP uses power-of-two length hash tables, which
     * Otherwise encounter collisions for Hashcodes that does not differ
     * in lower bits. Note:null keys always map to hash 0, thus index 0.
     * *
    Final int hash (Object k) {
        int h = hashseed;
        if (0!= h && k instanceof String) {return
            Sun.misc.Hashing.stringHash32 ((String) k);
        }

        H ^= K.hashcode ();

        This function ensures so hashcodes that differ only by
        //constant multiples in each bit position have a bounded
        //number of collisions (approximately 8 at default load factor).
        H ^= (H >>>) ^ (h >>>);
        Return h ^ (H >>> 7) ^ (H >>> 4);
    }


Remove

    /** * Removes and returns the entry associated with the specified key * in the HASHMAP.
     Returns NULL if the HASHMAP contains no mapping * for this key.
        * * Final entry<k,v> Removeentryforkey (Object key) {if (size = = 0) {return null; int hash = (key = = null)?
        0:hash (key);
        int i = indexfor (hash, table.length);
        Entry<k,v> prev = table[i];

        entry<k,v> e = prev;
            while (e!= null) {entry<k,v> next = E.next;
            Object K; if (E.hash = = Hash && (k = e.key) = = Key | | (Key!= null && key.equals (k)))
                {modcount++;
                size--;
                if (prev = = e) Table[i] = next;
                else Prev.next = next;
                E.recordremoval (this);
            return e;
            } prev = e;
       e = next; return e; }

Visible deletion of the time, HashMap did not resize.


ArrayList Initialization of

/**
     * Constructs a list containing
     the elements of the specified * collection, in of the order they are returned by T He collection ' s
     * iterator.
     *
     * @param c the collection whose elements are to is placed into this list
     * @throws NullPointerException if the s Pecified collection is null
     *
    /public ArrayList (collection<? extends e> c) {
        Elementdata = C.toarray ( );
        size = Elementdata.length;
        C.toarray might (incorrectly) not return object[] (= 6260652)
        if (Elementdata.getclass ()!= object[].class) 
  elementdata = arrays.copyof (elementdata, size, object[].class);
    }
which

/** * Copies the specified array, truncating or padding with nulls (if necessary) * So the copy has the Specifie  D length. For all indices this are * valid in both the original array and the copy, the two arrays would * contain Identica  L values.
     For any indices this are valid in the * copy but not the original, the copy would contain <tt>null</tt>.
     * Such indices would exist if and only if the specified length * was greater than that of the original array.
     * The resulting array is of the class <tt>newtype</tt>. * * @param original The array to is copied * @param newlength the length of the copy to is returned * @para 
     M newType the class of the copy to is returned * @return a copy of the original array, truncated or padded with nulls * To obtain the specified length * @throws negativearraysizeexception if <tt>newLength</tt> is Negative * @throws NullPointerException if;tt>original</tt> is null * @throws arraystoreexception If a element copied from * <tt>origi
     Nal</tt> is not of a runtime type this can stored in * A array of class <tt>newType</tt> * @since 1.6 */public static <T,U> t[] copyof (u[] original, int newlength, class<? extends t[]> N Ewtype) {t[] copy = ((object) NewType = = (object) object[].class)?
        (t[]) New Object[newlength]: (t[]) array.newinstance (Newtype.getcomponenttype (), newlength);
        System.arraycopy (original, 0, copy, 0, Math.min (original.length, newlength));
    return copy;
 }
The most common initialization method is

    /**
     * Constructs a empty list with an initial capacity of ten.
     * * Public
    ArrayList () {
        super ();
        This.elementdata = Empty_elementdata;
    }
The default is an array of 10 sizes.

Add

    /**
     * Appends the specified element to the "end of" this list.
     *
     * @param e element to is appended to this list
     * @return <tt>true</tt> (as specified by {@link Col Lection#add})
     */Public
    Boolean add (E e) {
        ensurecapacityinternal (size + 1);  Increments modcount!!
        elementdata[size++] = e;
        return true;
    }
This is called ensurecapacityinternal, which is to ensure that the array can hold enough elements
private void ensurecapacityinternal (int mincapacity) {
       if (Elementdata = = empty_elementdata) {
           mincapacity = Math.max (default_capacity, mincapacity);
       }
        Ensureexplicitcapacity (mincapacity);
}

private void ensureexplicitcapacity (int mincapacity) {
       modcount++;
        Overflow-conscious Code
       if (Mincapacity-elementdata.length > 0)
       grow (mincapacity);
}
The growth method is in the grow.

/**
     * Increases the capacity to ensure, it can hold at least the
     * number of elements specified by the minimum Capacity argument.
     *
     * @param mincapacity the desired minimum capacity * *
    private void Grow (int mincapacity) {
        //Overflow-c onscious code
        int oldcapacity = elementdata.length;
        int newcapacity = oldcapacity + (oldcapacity >> 1);
        if (newcapacity-mincapacity < 0)
            newcapacity = mincapacity;
        if (newcapacity-max_array_size > 0)
            newcapacity = hugecapacity (mincapacity);
        Mincapacity is usually close to size, and so is a win:
        Elementdata = arrays.copyof (Elementdata, newcapacity); 
  }
Obviously, each increase in the original length of half.

Remove

    /**
     * Removes the element at the specified position into this list.
     * Shifts any subsequent elements to the "left" (subtracts one from their
     * indices).
     * * @param index The "the" is
     removed * @return The element that is removed from the
     list
     * @throws indexoutofboundsexception {@inheritDoc}
     */public
    E-Remove (int index) {
        Rangecheck (index);

        modcount++;
        E OldValue = elementdata (index);

        int nummoved = size-index-1;
        if (nummoved > 0)
            system.arraycopy (Elementdata, index+1, Elementdata, index,
                             nummoved);
        Elementdata[--size] = null; Clear to let GC does its work return

        OldValue;
    }
Deletes the replication function of the calling system, and the size is automatically set.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.