Public class TestJava8 {public static void main (String [] args) {int count = 10000000; int [] k = new int [count]; Random r = new Random (); for (int j = 0; j <5; j ++) {for (int I = 0; I
Run on a pseudo-dual-core machine in the company. The gc () effect may also be mixed several times. The result is basically as follows:
1398:parallel:1373:serial:1224:parallel:1287:serial:1261:parallel:1274:serial:1304:parallel:1314:serial:1234:parallel:1480:serial:
In terms of results, concurrency still needs to be used when the data volume is large. However, whether memory sorting can be used for large data volumes is still a problem. For parallelSort, Java 8 still uses the Fork-Join mode. The effect on small data volumes is not good because it takes some time to start the thread. I personally think that Java 8 is better at making concurrent/non-concurrent judgments for the Arrays. sort () interface. After all, if multiple cores are hidden from java programmers, it is best to hide concurrent sort () to java programmers. Otherwise, you need to determine the data size at the upper layer, and then execute sort () or parallelSort (). In addition, the official data balancing process increases by at least 30%. This means that the official test runs out of a balanced dataset, but the dataset in the production environment is not balanced.
The biggest highlight of Java 8 is the lamda expression. You can use java for functional programming. What are the benefits?
1. If the lamda expression only performs read-only operations on variables, it must be threadSafe. In non-read-only situations, it is necessary to determine whether it is threadSafe.
2. threadSafe can be executed concurrently.
3. The results from the introduction of parameters are for API programming. (This is somewhat false)
4. The returned result can also be a function.
Write a piece of code as follows:
// Calculate the maximum value of public static void main (String [] args) in a List {List
K = new ArrayList
(); K. add (1); k. add (2); k. add (3); k. add (8); k. add (11); k. add (20); k. add (50); int max = Integer. MIN_VALUE; for (int j: k) {if (max <j) {max = j ;}} System. out. println (max );}
If finding the maximum value in this Code becomes a performance bottleneck, you need to change this code to concurrent operations. It is not easy to think about it. Now use the lamda expression to write:
// Calculate the maximum value of public static void main (String [] args) in a linked List {List
K = new ArrayList
(); K. add (1); k. add (2); k. add (3); k. add (8); k. add (11); k. add (20); k. add (50); Optional
Max = k. stream (). max (a, B)-> {return a-B;}); System. out. println (max );}
To change to concurrent operations, write as follows:
// Calculate the maximum value of public static void main (String [] args) in a linked List {List
K = new ArrayList
(); K. add (1); k. add (2); k. add (3); k. add (8); k. add (11); k. add (20); k. add (50); Optional
Max = k. parallelStream (). max (a, B)-> {return a-B;}); System. out. println (max );}
It's easy. Change k. stream () to k. parallelStream ()
This is simply based on the following points.
1. Write ThreadSafe functions or lamda expressions, which can easily be changed to multi-threaded operations.
2. Stream processing data.
3. The input parameter data is only related to the result of the previous step, but not the intermediate data generated by other data operations in this step.
4. Fork-Join provides a good multi-threaded framework.
Let's gossip about why Java 8 has done some things besides lamda expressions.
1. The default function interface in the interface. The reason is that the lamda expression is made for concurrency. Therefore, the concurrent package already has a lot of interfaces, hoping to be compatible with the previous version to reduce the migration workload. If an interface is added to the interface, the code before JDK 8 is compiled incorrectly. To solve this compilation error, you must either abstract an abstract class implementation interface and add the default implementation. You can also add this interface to all previous implementations. So I think this migration is a huge workload. Then the default function is born. In order not to write abstract class, and to use jdk5, jdk6, jdk7 code, you can easily migrate to jdk8. The default function is used as follows:
Public class TestF {public interface TestDefault {default void print () {System. out. println ("ew2we") ;}} public static void main (String [] args) {// write an anonymous class new TestDefault (){}. print ();}}
It is worth noting that if two interfaces implement the default function with the same name, an error will be reported during compilation.
2. SAM (single abstract method) is the Annotation @ FunctionalInterface. If this Annotation is included, this interface only has one unimplemented method. Of course, there can be multiple implemented default methods. This is done for the lamda expression. The lamda expression is like: (param list)-> {code statements;}, which can basically be considered as a function. Therefore, it is required that only one function method is not implemented to make the Code look good. @ FunctionalInterface:
@ FunctionalInterfacepublic interface DefaultInterface {default void hello () {System. out. println ("hello");} default void zzz () {System. out. println ("zzz");} void z (); // only one unimplemented function}
3. Stream is used to better use the Fork-Join framework. Stream is pipeline. For APIs that only care about input and output. Writing Stream code is very easy to implement concurrency. In fact, it is to throw a group of similar data into a pool, and then the thread pool starts to do things for the data. Before the execution is complete, join all the threads to put the final result into the final returned pool and return it. However, the simplest stream operation is convenient calling. It can be understood as a chain call. However, for the Style of code writing, try to write each call in different lines, which will facilitate debugging. The following is an example of Stream:
Public static void main (String [] args) {List
K = new ArrayList
(); K. add (1); k. add (2); k. add (3); k. add (8); k. add (11); k. add (20); k. add (50); // find the three numbers in the list greater than 2, and print them out k. parallelStream (). filter (a)-> {return a> 2 ;}). unordered (). limit (3 ). forEach (a)-> {System. out. println (a) ;}); // obtain the maximum value of the list element greater than 1. If no element in the list is greater than 1, Optional. emptyOptional is returned.
Max = k. parallelStream (). filter (a)-> {return a> 1 ;}). max (a, B)-> {return a-B;}); System. out. println (max );}
Here is a brief introduction to the syntax in lamda expressions. This lamda expression implements an abstract method. Therefore, you need to pay attention to whether the abstract method returns void, which is related to whether your expression contains return. the syntax of lamda is the parameter list. When there are 0 or more parameters, parentheses must be used. If there is only one parameter, parentheses can be omitted. Then there is an arrow->. Next is the function body. The function body must be enclosed by curly brackets. If there is only one statement, the curly brackets can be omitted. The following lamda expressions are correct.
a -> return a+1;(a) -> return a+1;(a) -> {return a+1;}(a,b) -> {int c = a+b; return c>>1;}()->System.out.println("empty");
Note the final variable and this pointer.
Import java. util. arrayList; import java. util. arrays; import java. util. list; import java. util. optional; public class TestLamba {public static class Score {int score; public List
FindLarger (List
Scores) {List
Tmp = new ArrayList
(); // Note that this is the thisscores of the Score Object. stream (). filter (a)-> {return a> this. score ;}). forEach (a)-> {tmp. add (a) ;}); return tmp;} public static List
FindLarger (List
Scores, Score myScore) {List
Tmp = new ArrayList
(); // MyScore = new Score (); compile wrong // here, myScore is semantic final, but the domain in myScore can be changed // myScore. score = 3; this is correct and is also correct in the lamda expression. // For myScore, the lamda expression is not threadSafescores. stream (). filter (a)-> {return a> myScore. score ;}). forEach (a)-> {tmp. add (a) ;}); return tmp ;}} public static void main (String [] args) {Arrays. asList (). forEach (a)-> System. out. println ("I'm" + a); List
K = new ArrayList
(); K. add (1); k. add (2); k. add (3); k. add (8); k. add (11); k. add (20); k. add (50); Score s = new Score (); s. score = 11; s. findLarger (k ). forEach (a-> {System. out. println (a) ;}); System. out. println ("dsdsd"); Score. findLarger (k, s ). forEach (a-> {System. out. println ();});}}
There is no final variable in the parameter. In terms of syntax, Java 8 does not require that the external reference parameter be final, but the semantics is still final. This is similar to the anonymous internal class. In addition, this pointer must be a pointer to the outer class. The lamda expression does not have this.
Now java jdk may easily use multi-core resources. Therefore, it is expected that jdk In The Future of java will be able to use resources of multiple machines, such as map/reduce. This will make it easier to write programs. It looks like this trend ~~~ Continue to evolve ~