java source code - AbstractMap

AbstractMap abstract class implements a simple and versatile method itself is not difficult. But there are two methods of great concern, keySet and methods to achieve values ​​can source the value of learning in this abstract class.

  An abstract class is typically implemented as a skeleton, a common method to handle each subclass. Previous We explained the Map interface, Cipian to analyze AbstractMap abstract class research.

  Map Java type of data structure in a considerable number, as their skeleton AbstractMap implemented method implements Map interface portion, i.e. provide a common way for its various subclasses Map, unimplemented methods may have various Map different.

  Abstract classes can not be the new keyword to create an instance of an abstract class directly, but it can have a constructor. AbstractMap provides a protected modified constructor with no arguments, it means that only subclasses can access (of course, it is itself an abstract class, other classes can not directly instantiate it), that is to say only to its subclasses call the constructor with no arguments.

  In Map interface defines an inside Entry Interface , this interface is implemented inside Map or for maintaining a key-value key-value pair , the key-value stored in Map.Entry in. AbstractMap this internal interface implementation , a total of two : one is variable SimpleEntry and a are immutable SimpleImmutableEntry .

(A)SimpleEntry

  public static class SimpleEntry<K,V> implements Entry<K,V>, java.io.Serializable

It is relatively simple values stored-value operation for the key value is defined is a final modification means is a non-reference change . In addition its setValue method is a little special , stored value value return value is not stored, but before the old value is returned .

private final K key;
private V value;
public SimpleEntry(K key, V value) {
     this.key   = key;
     this.value = value;
}
public SimpleEntry(Entry<? extends K, ? extends V> entry) {
     this.key   = entry.getKey();
     this.value = entry.getValue();
}public V setValue(V value) {
     V oldValue = this.value;
     this.value = value;
     return oldValue;
}
....

It is important to learn is rewritten it equals and hashCode methods.

public  Boolean equals (Object O) {
     IF (! (O the instanceof Map.Entry)) // check whether it Map.Entry type equals equal to one and the same type must first 
        return  to false ; 
    Map.Entry <,??> = E (Map.Entry <,??>) O; // "?" Object type strongly into the Map.Entry type, parameters used herein instead of "K, V" because the generic type at runtime is erased 
                          // compiler does not know the specific K, V is what type of
return eq (Key, e.getKey ()) && eq (value, e.getValue ()); // Key and value are calling eq method ( built ) judgment, equals are equal when return ture. }
// methods built eq
Private  static  boolean EQ (Object o1, Object o2) {
      return o1 == null o2 ==? null : o1.equals (o2);     
// this ternary operator is also very simple, but important to note that although the o1 , o2 of type Object, Object type equals method is through the "==" comparison of reference,
  // so do not think there is a problem, because in practice, o1 type likely String, Object despite being turned up, so this when you call the equals method is called String # equals method.
}
public  int hashCode () {
      // value and the key value is not null, the hashCode thereof XORed. 
     return (Key == null 0: key.hashCode ()?) ^ (value == null 0? : value.hashCode ());     
 }

 (B)SimpleImmutableEntry

  public static class SimpleImmutableEntry<K,V> implements Entry<K,V>, java.io.Serializable

  Defined as immutable in the Entry , in fact, is the fact that can not be changed, because it does not provide a setValue method, simultaneous access by multiple threads natural time can not be modified by the setValue method .

  Compared to SimpleEntry its key and value member variables are defined for final type . Call setValue method will throw an UnsupportedOperationException exception.

     It's equals and hashCode methods and SimpleEntry consistent.

Private  Final K Key; // attribute are set to the Final 
Private  Final V value;
 // with a value k and the method of obtaining 
public K getKey () {   return Key;}
 public V the getValue () { return value;}
 // not set method, this method is invoked, an exception is thrown 
public V the setValue (V value) { the throw  new new an UnsupportedOperationException ();}

 

Abstract class method implementation AbstractMap

====== Query Operations query , get the size, is empty, the existence of, access to data and other content

public int size()

  Map entrySet defines a method that returns a collection of Map.Entry Set directly call the method Set size collection that is the size of the Map.

public boolean isEmpty()

  Call the above method size, equal to 0 that is empty.

public boolean containsKey(Object key)

  Implementation of this method is simple, traverse Map.Entry by calling the iterator Set entrySet method to get the set, compared with the parameter key. Map key may be stored as a null value, since in the storage key = null special Map (hashCode value can not be calculated), where it is determined whether the parameter is also done key is empty.

public boolean containsValue(Object value)

  This method of implementation and consistent containsKey.

public V get(Object key)

  The two above-implemented method is similar, except that the return is equal to the above boolean, this method returns the value value.

=========== Modification the Operations modification operations, add, delete, etc.

public V put(K key, V value)

  Methods key into key-value pairs to a Map and no concrete realization , will direct throw an UnsupportedOperationException.

public V remove(Object key)

  Specifies to delete the Map parameter key key-value pairs. This method is very simple, is traversed by the iterator Set Map.Entry collection, find the corresponding key value, delete Map.Entry by calling Iterator # remove method.

===========  Bulk the Operations batch operations , batch delete, empty the whole

public void putAll(Map<? extends K, ? extends V> m)

  This method is very simple traversal of incoming Map, calls the method put into it.

public void clear()

  Set call entrySet method to get a collection and then call Set # clear () method empty.


 

We mainly look at keySet values ​​and methods.

// source structure 
transient
the Set <K> keySet; // modified transient keyword indicates variables will no longer be part of object persistence, the variable content after serialization can not gain access. The English word meaning: short | instantaneous transient Collection <V> values; public Set <K> keySet () {...} // return the set of Map key value Set public Collection <V> values () {. Map value ..} // return the set of values collection

 

public Set<K> keySet()

  Returns the key value Set the set, it is natural can think of a simple implementation, the array traversal Entry into Set out key value set, which means that each call keySet methods will traverse Entry array, data is greater efficiency Greatly reduced.

  The JDK source code how to solve it? keySet method of internal re- implement a new custom Set collection , in this custom Set collection in and rewrite the iterator method , here is the key , iterator method returns Iterator interface , but here they re-implement the Iterator iterator , by call entrySet method then calls its iterator method . Analysis following binding code:

public the Set <K> keySet () { 
    the Set <K> KS = keySet;         // transient defined in the Set <K> keySet 
    IF (== KS null ) {         // first call certainly is null, the code to create the following set an exemplary 
        KS = new new the AbstractSet <K> () {         // create a custom set 
            public the Iterator <K> iterator () {         // override iterator method set set 
                return  new new the Iterator <K> () {     // re iterator interface implement 
                    Private iterator <Entry <K, V = the entrySet >> I () iterator ();.     // reference set of Entry set iterator iterator 
                    public  Booleanthe hasNext () {
                         return i.hasNext ();         // for determining the key value is determined on the entry 
                    }
                     public K Next () {
                         return i.next () getKey ();.     // Remove a key value, It is to take # getKey entry 
                    }
                     public  void remove () { 
                        i.remove ();     // delete key value is deleted entry 
                    } 
                }; 
            } 
            public  int size () {     // rewritable Set # size method 
                return AbstractMap. the this.size ();     // Key Map is the whole value of the number of how much, so call this method to the class size. 
                               // This is an internal class, direct use of this keyword on behalf of the class, should indicate whether the method call AbstractMap in size, it means that this is no static static method
} public boolean isEmpty () { // the Set # isEmpty overridden method return . AbstractMap the this .isEmpty (); // for whether a key value that determines whether the air Map ,, therefore call this method may be isEmpty class } public void Clear () { // the Set # overridden method Clear . AbstractMap the this .clear (); // clear key value, it is clear Map ,, call this method may be clear class } public Booleanthe contains (Object K) { // rewriting Set # contains methods return AbstractMap. the this .containsKey (K); // Analyzing Data Set contains k, is to determine whether the Map contains the key value, the method call of this class containsKey i.e. can } }; keySet = KS; // this set of custom Set assigned to the variable keySet, keySet method is invoked again in the future, because keySet is not null, just return directly. } Return KS;

 

  Although this method is around key value , but in fact can combine Entry to achieve , but without traversing Entry , while the above mentioned iterator method call entrySet #, here is the template method pattern of best practices .

  Because entrySet and AbstractMap in unrealized , but handed over its subclasses to complete , but for keySet method but it can be a "skeleton algorithm" to achieve, this is the template method pattern .

public Collection<V> values()

  For the reference values ​​can then keySet method, both with the same purpose, here omitted to save space.

public abstract Set<Entry<K,V>> entrySet()

  An abstract method, to its subclasses to complete, indicating that this method is not particularly "universal."

public boolean equals(Object o)

  Map prescribed only in the Map in each pair of key-value key-value pairs of key and value all  the time correspondence their equals compare returns it to true . In the method first determines simple condition, if the references are equivalent , directly returns to true , if the parameter type o Map not directly return to false , if both the number of different Map directly returns to false . Back before it traverses the array Entry comparison Entry of the key and value if one correspondence . The method is simple, but it gives us a revelation, in the conditional, the first simple basic judgment, and then judge complex.

public int hashCode()

  Rewrite the equals method of the Object class, override hashCode also necessary. AbstractMap to implement the hashCode is all Map.Entry (this is SimpleEntry or SimpleImmutableEntry) The hashCode value to add, as a conclusion that the sum of the value of the Map hashCode.

public String toString()

  This method is nothing to say, is to remove all key-value pairs using StringBuilder be spliced.

protected Object clone() throws CloneNotSupportedException

  Achieve a shallow copy, because it is shallow copy keySet for variables and values is not to copy, to prevent problems caused by two shallow copy, clone method on Object in the "million class father --Object" has been resolved.

 

Thanks: https: //www.cnblogs.com/yulinfeng/p/8486539.html

Guess you like

Origin www.cnblogs.com/FondWang/p/11918939.html