Summary of operational optimization of Set Class (Iii.)

Source: Internet
Author: User
Tags comparable

Collection Class Practice

ArrayList, Vector, LinkedList are all from the implementation of Abstractlist, and Abstractlist directly implemented the List interface, and extended from Abstarctcollection. ArrayList and vectors use an array implementation, ArrayList does not provide thread synchronization for any one method, so it is not thread-safe, and most of the methods in the vector do thread synchronization, which is a thread-safe implementation. LinkedList uses a circular doubly linked list data structure, which is connected by a series of table items, and a table entry always contains 3 parts, element content, precursor table entries, and back drive table entries.

The capacity needs to be expanded when ArrayList exceeds the size of the current array. During the expansion process, a large number of array copy operations are performed, and when the array is copied, the System.arraycopy () method is eventually called. LinkedList because of the use of the structure of the linked list, so there is no need to maintain the size of the capacity, but each time the element increases the need to create a new Entry object, and more assignment operations, in the frequent system calls, the performance will have a certain impact, The creation of new objects without interruption or a certain amount of resources is consumed. Because of the continuity of the array, it is always possible to add elements at the end, only to generate array expansions and arrays when there is insufficient space.

ArrayList is an array-based implementation, and an array is a contiguous memory space, and if an element is inserted anywhere in the array, it is inevitable that all elements after that position need to be rearranged, so it is inefficient to insert data into the trailer whenever possible. LinkedList does not cause performance degradation by inserting data.

After each valid element delete operation of ArrayList, the array is reorganized, and the position of the deleted element is higher, the higher the cost of the array reorganization, the lower the cost of the element to be removed. LinkedList to remove the intermediate data, you need to conveniently complete the half List.

Listing 4. ArrayList and LinkedList using code
Import java.util.arraylist;import java.util.linkedlist;public class arraylistandlinkedlist  { public static void main (String[] args) { long start =  System.currenttimemillis ();  arraylist list = new arraylist ();  Object obj  = new object ();  for (int i=0;i<5000000;i++) { list.add (obj);  } long  end = system.currenttimemillis ();  system.out.println (End-start);   start =  system.currenttimemillis ();  linkedlist list1 = new linkedlist ();  Object  obj1 = new object ();  for (int i=0;i<5000000;i++) { list1.add (obj1);  } end = system.currenttimemillis ();  system.out.println (End-start);   start =  system.currenttimemillis ();  object obj2 = new object ();  for (int i=0;i <1000;i++) { liSt.add (0,OBJ2);  } end = system.currenttimemillis ();  system.out.println (End-start);   start = system.currenttimemillis ();  object obj3 = new object ();  for (int i=0;i<1000;i++) { list1.add (obj1); } end =  System.currenttimemillis ();  system.out.println (End-start);  start =  System.currenttimemillis ();  list.remove (0);  end = system.currenttimemillis ();  System.out.println (End-start);   start = system.currenttimemillis ();  list1.remove ( 250000);  end = system.currenttimemillis ();  system.out.println (End-start);    }}

Listing 5. Run output
639129669690015

HashMap is to make the key hash algorithm, and then map the hash value to the memory address, directly get the data corresponding to the key. In HashMap, the underlying data structure uses an array, the so-called memory address, which is the subscript index of the array. HashMap's high performance needs to ensure the following points:

    1. The Hash algorithm must be efficient;

    2. The algorithm of Hash value to memory address (array index) is fast;

    3. The corresponding value can be obtained directly based on the memory address (array index).

HashMap is actually an array of linked lists. As mentioned earlier, the implementation mechanism of HASHMAP-based linked list, as long as the hashcode () and the Hash () method to achieve good enough to minimize the generation of conflicts, then the operation of the HASHMAP is almost equivalent to the random access operation of the array, with good performance. However, if the hashcode () or Hash () method is poor, in the case of a large number of conflicts, HashMap in fact degenerate into a few linked lists, the operation of HashMap is equivalent to traversing the linked list, when performance is poor.

One of the drawbacks of HASHMAP is its disorder, the element that is deposited into the HashMap, whose output is unordered when traversing HashMap. If you want elements to remain in the order of input, you can use Linkedhashmap overrides.

Linkedhashmap inherits from the HashMap, has the efficiency, at the same time on the basis of HASHMAP, but also inside adds a chain list, holds the element the order.

The HASHMAP uses the hash algorithm to perform the Put () and Get () operations as quickly as possible. The TREEMAP provides a completely different MAP implementation. Functionally, TREEMAP has a more powerful function than HashMap, which implements the SortedMap interface, which means it can sort elements. The performance of the TREEMAP is slightly lower than HashMap. If you need to sort elements in development, you won't be able to do this with HASHMAP, and the iteration output using TREEMAP will be in element order. Linkedhashmap are ordered based on the order in which elements enter the collection or are accessed, and TreeMap are based on the intrinsic order of the elements (determined by Comparator or comparable).

Linkedhashmap are sorted according to the order in which the elements are added or accessed, while TreeMap are sorted according to the Key of the element.

The code shown in Listing 6 illustrates the ordering of business logic using TREEMAP.

Listing 6. TREEMAP implementation Sequencing
import java.util.iterator;import java.util.map;import java.util.treemap;public class  Student implements comparable<student>{public string name;public int score ;p ublic student (string name,int score) {this.name = name;this.score = score;} @Override//Tell  TreeMap  how to sort Public int compareto (Student o)  {// TODO  AUTO-GENERATED&NBSP;METHOD&NBSP;STUBIF (O.score<this.score) {return 1;} Else if (O.score>this.score) {return -1;} return 0;} @Overridepublic  string tostring () {stringbuffer sb = new stringbuffer (); sb.append ("Name:"); Sb.append (name); Sb.append (" "); Sb.append ("Score:"); Sb.append (score); return sb.tostring ();} Public static void main (String[] args) {treemap map = new treemap (); Student s1 = new student ("1", 100); student s2 = new Student ("2", 99); Student s3 = new student ("3", 97); Student s4 = new student ("4"), Map.put (S1, new studentdetailinfo (S1)); Map.put ( S2, new studentdetailinfo (S2)); Map.put (S3, new studentdetailinfo (S3)); Map.put (s4, new  studentdetailinfo (S4));//Print the number of people map map1= ((TREEMAP) map) between  S4  and  S2 . SubMap (S4, &NBSP;S2); for (Iterator iterator=map1.keyset (). Iterator (); Iterator.hasnext ();) {student key =   (Student) iterator.next (); System.out.println (key+ "," +map.get (key));} System.out.println ("Submap end");//print score ratio  s1  Low person map1= ((TREEMAP) map). Headmap (S1); for (Iterator  iterator=map1.keyset (). iterator (); Iterator.hasnext ();) {student key =  (Student) Iterator.next (); System.out.println (key+ "," +map.get (key));} System.out.println ("Submap end");//print scores higher than  s1  people map1= ((TREEMAP) map). Tailmap (S1); for (Iterator  iterator=map1.keyset (). iterator (); IteratOr.hasnext ();) {student key =  (Student) iterator.next (); System.out.println (key+ "," +map.get (key));} System.out.println ("Submap end");}} Class studentdetailinfo{student s;public studentdetailinfo (student s) {This.s = s ;} @Overridepublic  string tostring () {return s.name +  "' S detail information";}}

Listing 7: Running the output
Name:4 score:91->4 ' s detail informationname:3 score:97->3 ' s detail informationsubmap endname:4 score:91->4 ' s Detail Informationname:3 score:97->3 ' s detail informationname:2 score:99->2 ' s detail informationsubmap endname:1 Score:100->1 ' s detail informationsubmap end

The Weakhashmap feature is that if there is no other reference to this key, the MAP will automatically discard the value, except that it has a reference to the key itself. The code shown in Listing 8 declares two Map objects, one is HashMap, the other is Weakhashmap, and A and B two objects are placed into two maps, and when HashMap deletes a, and both A and B point to Null, Weakhashmap A will automatically be recycled. The reason for this is that, for a object, when HashMap is removed and a is pointed to Null, there is no pointer to a in addition to the Weakhashmap, so Weakhashmap will automatically discard a, while for the B object it points to NULL, but there is also a pointer to B in HashMap, so Weakhashmap will keep the B object.

Listing 8.WeakHashMap Sample Code
import java.util.hashmap; import java.util.iterator; import java.util.map;  import java.util.weakhashmap; public class weakhashmaptest {  public  Static void main (String[] args)  throws exception {  string a  = new string ("a");   string b = new string ("B");   Map  weakmap = new weakhashmap ();   map map = new hashmap ();   map.put (a,  "AAA"),   map.put (b,  "BBB"),  weakmap.put (a,  "AAA");   weakmap.put (b,  "BBB");  map.remove (a);  a=null;  b=null; system.gc ();   iterator i = map.entryset (). Iterator ();  while  (I.hasnext ())  {   Map.Entry en =  (Map.entry) I.next ()   system.out.println ("Map:" +en.getkey () + ":" + En.getvalue ()); &NBSP;&NBSP;}&NBSp; iterator j = weakmap.entryset (). Iterator ();  while  (J.hasNext ())  {   Map.Entry en =  (Map.entry) J.next ()   system.out.println ("Weakmap:" + En.getkey () + ":" +en.getvalue ());   }  } }

Listing 9: Running the output
map:b:bbbweakmap:b:bbb

Weakhashmap mainly through the function of expungestaleentries to remove its internal unused items, so as to achieve the purpose of automatic memory release. Basically, this function is called when the content of the weakhashmap is accessed, so that it clears entries that are no longer external references to them. But wouldn't it be possible to free up memory if Weakhashmap was pre-generated and the weakhashmap was never accessed before the GC?

Listing 10. WeakHashMapTest1
Import Java.util.arraylist;import Java.util.list;import Java.util.weakhashmap;public class WeakHashMapTest1 {public static void Main (string[] args) throws Exception {list<weakhashmap<byte[][], byte[][]>> maps = new arraylist& Lt Weakhashmap<byte[][], byte[][]>> ();  for (int i = 0; i < i++) {weakhashmap<byte[][], byte[][]> d = new weakhashmap<byte[][], byte[][]> (); D.put (New byte[1000][1000], new byte[1000][1000]); Maps.add (d); System.GC (); System.err.println (i); } }}

Run the code shown in listing 10 without changing any JVM parameters, because the Java default memory is 64M, throwing out memory overflow error.

Listing 11. Run output
241242243Exception in thread "main" Java.lang.OutOfMemoryError:Java Heap spaceat Weakhashmaptest1.main ( WEAKHASHMAPTEST1.JAVA:10)

Sure enough, weakhashmap this time does not automatically help us to release the unused memory. The code shown in listing 12 does not present a memory overflow issue.

Listing 12. WeakHashMapTest2
Import Java.util.arraylist;import Java.util.list;import Java.util.weakhashmap;public class WeakHashMapTest2 {public static void Main (string[] args) throws Exception {list<weakhashmap<byte[][], byte[][]>> maps = new arraylist& Lt Weakhashmap<byte[][], byte[][]>> ();  for (int i = 0; i < i++) {weakhashmap<byte[][], byte[][]> d = new weakhashmap<byte[][], byte[][]> (); D.put (New byte[1000][1000], new byte[1000][1000]); Maps.add (d); System.GC (); System.err.println (i); for (int j = 0; J < i; J + +) {System.err.println (j + "size" + Maps.get (j). Size ());}} }}

The result of the operation shows that the test output is normal and there is no memory overflow problem.

In general, Weakhashmap is not what you do it can automatically release objects that are not used internally, but instead release objects that are not used when you access its content.

Weakhashmap implements a weak reference because its entry<k,v> is inherited from Weakreference<k>,

The class definitions and constructors in weakhashmap$entry<k,v> are shown in Listing 13.

Listing 13. Weakhashmap class definition
private static class Entry<k,v> extends Weakreference<k> implements map.entry<k,v> Entry (K key, V value , referencequeue<k> queue,int Hash, entry<k,v> next) {Super (key, queue); this.value = value; This.hash = Hash ; This.next = Next; }

Notice that it constructs the statement of the parent class: "Super (key, queue);", which is the key, so key is the weak reference, and Value is a direct strong reference in This.value. At System.GC (), the Byte array in Key is recycled, and value remains (value is strongly associated to Entry, Entry is associated with the map, and map is associated with ArrayList).

Each time a new weakhashmap is made for the For loop, after the Put operation, although the GC recycles the Byte array in the WeakReference Key and notifies the referencequeue of the event, there is no corresponding action to trigger Weakhashmap to deal with Referencequeue, so weakreference packaging Key still exists in the Weakhashmap, the corresponding value of course exists.

When was the value cleared? Analysis of listing 10 and listing 112 sample programs shows that Maps.get (j) of listing 11. Size () triggers the recovery of Value, so how does it trigger? View Weakhashmap Source The Size method calls the Expungestaleentries method, which iterates through the Entry (Quene) The JVM is about to reclaim, and empties the Entry Value to reclaim memory. So the effect is that key is cleared during GC and Value is cleared after key is cleared for access to Weakhashmap.

The Weakhashmap class is thread-out-of-sync, and you can use the Collections.synchronizedmap method to construct a synchronized weakhashmap, where each key object is stored indirectly as an indication object of a weak reference. Therefore, the key is removed automatically, either within the map or outside the map, only after the garbage collector clears the weak reference for a key. It is important to note that the value object in Weakhashmap is persisted by a normal strong reference. Therefore, care should be taken to ensure that the value object does not strongly refer to its own key directly or indirectly because it prevents the key from being discarded. Note that a value object can indirectly refer to its corresponding key through the weakhashmap itself, which means that a value object may strongly refer to some other key object, while the value object associated with the key object will instead strongly refer to the key of the first value object.

One way to deal with this problem is to wrap the value itself in weakreferences before inserting it, such as: M.put (Key, new WeakReference (value)), and then unpack it with GET, all collection view methods for that class The iterator returned is a quick failure, and after the iterator is created, if the mapping is modified from the structure, the iterator will throw a change in any way, except through the Remove or Add method of the iterator itself, any other time. Concurrentmodificationexception. Thus, in the face of concurrent modifications, the iterator will soon fail completely, rather than risking any uncertainty at any time in the uncertain future.

Note that we cannot ensure that iterators do not fail, and in general, there is no guarantee that any fully deterministic can be made when there are concurrent changes that are out of sync.

Summarize

Combining the previous introduction and the example code, we can know that if it involves stacks, queues and other operations, you should consider using List. For operations that require quick insertion, deletion of elements, and so on, you should use LinkedList. If you need to quickly randomly access elements, you should use ArrayList. If the program is in a single-threaded environment, or if access is done only in one thread, it is more efficient to consider non-synchronous classes. If multiple threads might manipulate a class at the same time, the synchronized class should be used. Pay special attention to the operation of the hash table, and the object as Key should correctly replicate the Equals and Hashcode methods. Try to return the interface rather than the actual type, such as returning a List instead of ArrayList, so that if you need to change ArrayList to LinkedList later, the client code does not have to be changed, which is the idea of programming for abstraction.

This article is only for application-level sharing, subsequent articles will be specific to the implementation of the source code level in-depth introduction, but also on the specific implementation of the algorithm based on an in-depth introduction, please have the needs of readers concerned about the following articles.


Summary of operational optimization of Set Class (Iii.)

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.