"Java8" Use Java8 's foreach Loop with caution

Source: Internet
Author: User

Although java8 out for a long time, but has not been used before, recently just learned Java8, recommended a book or a good < for busy people to see the javase8>. Because of learning Java8, so as long as can use the place will go to use, especially Java8 stream, feel very convenient to use, because Dot point is out, and the code is so concise. Now begin to understand the java8 slowly, found that many things can not look at the surface.

For example, a regular traversal of a collection, here is an example:

1. First traverse a list

Way 1. At the outset:

 Public Static void test1 (list<string> List) {  for (int i = 0; i < list.size (); i++  ) {    System.out.println (List.get (i));}  }

Way 2. Of course a little more advanced is this:

 Public Static void test2 (list<string> List) {  for (int i = 0,lengh=list.size (); I < Lengh; i++) {    System.out.println (List.get (i));}  }

Way 3. There is also the iterator traversal:

 Public Static void test3 (list<string> List) {  Iterator<String> Iterator =  List.iterator ();    while (Iterator.hasnext ()) {    System.out.println (Iterator.next ());}  }

Way 4. Later there was an enhanced for loop:

 Public Static void test4 (list<string> List) {  for(String str:list) {    System.out.println (str);}  }

The way 5.java8 is added later:

 Public Static void test5 (list<string> List) {  //List.foreach (system.out:: PRINTLN); and the following notation is equivalent to  List.foreach (str->{    System.out.println (str);  });}

Way 6. There is another:

 Public Static void test6 (list<string> List) {  list.iterator (). foreachremaining (str,{    System.out.println (str);  });

There should be no other, the above six methods, according to my usage habits 5 most commonly used, 4 occasionally used, the other basic is not how to use, the reason for using 5 is because convenient to write, the hint can be written out, occasionally use 4 reason is that 5 inconvenient to count with, the following performance test, string does not have representative, Decide to use the object, a simple test class is as follows:

A simple test, the content does not care too much, simple calculation hashcode:

 Packagetest;Importjava.util.ArrayList;ImportJava.util.Iterator;Importjava.util.List; Public classTest8 { Public Static voidMain (string[] args) {List<Dog> list=NewArraylist<>();  for(inti=0;i<10;i++) {List.add (NewDog (i, "dog" +i)); }    LongNanotime =System.nanotime ();    Test1 (list); LongNanoTime1 =System.nanotime ();    Test2 (list); LongNanoTime2 =System.nanotime ();    TEST3 (list); LongNanoTime3 =System.nanotime ();    TEST4 (list); LongNanoTime4 =System.nanotime ();    TEST5 (list); LongNanoTime5 =System.nanotime ();    TEST6 (list); LongNanoTime6 =System.nanotime (); System.out.println ((nanoTime1-nanotime)/1000000.0); System.out.println ((nanoTime2-NANOTIME1)/1000000.0); System.out.println ((NanoTime3-NANOTIME2)/1000000.0); System.out.println ((NanoTime4-NANOTIME3)/1000000.0); System.out.println ((NanoTime5-NANOTIME4)/1000000.0); System.out.println ((NanoTime6-NANOTIME5)/1000000.0); } Public Static voidTest1 (list<dog>list) {   for(inti = 0; I < list.size (); i++) {list.get (i). Hashcode (); }} Public Static voidTest2 (list<dog>list) {   for(inti = 0,lengh=list.size (); i < Lengh; i++) {list.get (i). Hashcode (); }} Public Static voidTest3 (list<dog>list) {Iterator<Dog> iterator =List.iterator ();  while(Iterator.hasnext ()) {Iterator.next (). Hashcode (); }} Public Static voidTest4 (list<dog>list) {   for(Dog dog:list) {dog.hashcode (); }} Public Static voidTEST5 (list<dog>list) {  //List.foreach (system.out::p rintln), and the following notation is equivalentList.foreach (dog->{dog.hashcode (); });} Public Static voidTest6 (list<dog>list) {List.iterator (). foreachremaining (Dog-{dog.hashcode (); });}}classdog{Private intAge ; PrivateString name;  PublicDog (intAge , String name) {    Super();  This. Age =Age ;  This. Name =name; }   Public intGetage () {returnAge ; }   Public voidSetage (intAge ) {     This. Age =Age ; }   PublicString GetName () {returnname; }   Public voidsetName (String name) { This. Name =name; } @Override PublicString toString () {return"Dog [age=" + Age + ", name=" + name + "]"; }}
View Code

Run three averaging, machine configuration is not said, because I am not the absolute value of comparison, I am comparing the relative values of these methods, data results, the trend chart is as follows:

And then remove the performance has been very stable way 5 and millions data, to analyze the results:

Can be a very scary result, java8 foreach each cycle of time is more than 100 milliseconds, although it is more stable (as the advantage of it). Therefore, the following conclusions are drawn:

In normal use (less than millions of data), Normal (non-parallel) traversal of a collection:

    • Do not use Java8 foreach for up to 100 milliseconds each time
    • Calculate the size of the normal for loop in advance, the time is minimal, but writing trouble
    • Enhanced for loop good performance
2. Iterate over a set again

Test the hashset in the same way as the following:

 Packagetest;ImportJava.util.HashSet;ImportJava.util.Iterator;ImportJava.util.Set; Public classTest9 { Public Static voidMain (string[] args) {Set<Dog> set =NewHashset<>();  for(inti = 0; i < 10_000_000; i++) {Set.add (NewDog (i, "dog" +i)); }    LongNanotime =System.nanotime ();    Test1 (set); LongNanoTime1 =System.nanotime ();    Test2 (set); LongNanoTime2 =System.nanotime ();    Test3 (set); LongNanoTime3 =System.nanotime ();    Test4 (set); LongNanoTime4 =System.nanotime (); System.out.println ((nanoTime1-Nanotime)/1000000.0); System.out.println ((nanoTime2-nanoTime1)/1000000.0); System.out.println ((NanoTime3-nanoTime2)/1000000.0); System.out.println ((NanoTime4-NanoTime3)/1000000.0); }   Public Static voidTest1 (set<dog>list) {Iterator<Dog> iterator =List.iterator ();  while(Iterator.hasnext ()) {Iterator.next (). Hashcode (); }  }   Public Static voidTest2 (set<dog>list) {     for(Dog dog:list) {dog.hashcode (); }  }   Public Static voidTest3 (set<dog>list) {List.foreach (dog-{dog.hashcode ();  }); }   Public Static voidTest4 (set<dog>list) {List.iterator (). foreachremaining (Dog-{dog.hashcode ();  }); }}
View Code

The following results are calculated:

It is not difficult to find that the Java8 foreach still takes more than 100ms each time, the fastest becomes enhanced for loop, iterator traversal and Java8 iterator (). Foreachremaining almost.

3. Finally traverse the map

Still testing the Map collection traversal in the same way, the test class is as follows:

 Packagetest;ImportJava.util.HashMap;ImportJava.util.Iterator;ImportJava.util.Map;ImportJava.util.Set; Public classTest10 { Public Static voidMain (string[] args) {Map<string, dog> map =NewHashmap<>();  for(inti = 0; i < 1000_000; i++) {Map.put ("Dog" + I,NewDog (i, "dog" +i)); }    LongNanotime =System.nanotime ();    Test1 (map); LongNanoTime1 =System.nanotime ();    Test2 (map); LongNanoTime2 =System.nanotime ();    TEST3 (map); LongNanoTime3 =System.nanotime ();    TEST4 (map); LongNanoTime4 =System.nanotime (); System.out.println ((nanoTime1-Nanotime)/1000000.0); System.out.println ((nanoTime2-nanoTime1)/1000000.0); System.out.println ((NanoTime3-nanoTime2)/1000000.0); System.out.println ((NanoTime4-NanoTime3)/1000000.0); }   Public Static voidTest1 (map<string, dog>map) {Iterator<map.entry<string, dog>> entries =Map.entryset (). iterator ();  while(Entries.hasnext ()) {Map.entry<string, dog> entry =Entries.next (); intCode=entry.getkey (). Hashcode () +Entry.getvalue (). Hashcode (); }  }   Public Static voidTest2 (map<string, dog>map) {     for(Map.entry<string, dog>Entry:map.entrySet ()) {      intCode=entry.getkey (). Hashcode () +Entry.getvalue (). Hashcode (); }  }   Public Static voidTest3 (map<string, dog>map) {     for(String key:map.keySet ()) {intCode=key.hashcode () +Map.get (key). Hashcode (); }  }   Public Static voidTest4 (map<string, dog>map) {Map.foreach (key, value)- {      intCode=key.hashcode () +Value.hashcode ();  }); }}
View Code

The results are as follows:

Java8 's foreach continues to live up to expectations, and the quickest is to enhance the For loop.

+ Final Conclusion

Normal (order of magnitude 10W, non-parallel) traverse a collection (List, Set, MAP) If you care about efficiency, do not use Java8 foreach, although it is very convenient and elegant

Any time you use the enhanced for loop you are not the second choice

"Java8" Use Java8 's foreach Loop with caution

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.