Categories
Uncategorized

jdk13 is coming, jdk8 of these points should look!

Explanation

jdk8 despite a long time, but we could still have a lot of people not too familiar with this paper is to introduce illustrate some jdk8 relevant content.

Main will explain:

    lambda expressions

    Method references

    The default method

  • Stream
  • Optional replaced with a null

    New log and time

  • CompletableFuture
  • To (the PermGen) is replaced by a permanent addition to substituting element space (Metaspace)

Let’s look at Ali norms which involves jdk8 related content:

jdk8 opening

https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html

There are:

1: lambda expression: A new language features to the parameters as a function of the method or as a data code. lambda expression shows an example in your function interface (an interface with a single process) is more compact.

2: a simplified method references lambda expression is written, the referenced method is actually a method to achieve body lambda expressions, so to make the code easier to read

3: The default method: Java 8 introduction default method, or called virtual extension method, the purpose is to allow the interface to add new methods afterwards without forcing all classes that implement this interface are provided to realize the new method. That is its main usage scenario might involve the evolution of the code.

4: Stream not set elements, nor is the data structure, which is equivalent to an advanced version of Iterator, which can not be repeated traversal of data, like water, flows through the gone forever. It is ordinary Iterator different is that it can traverse parallel, serial common Iterator can only be executed in a thread. Operations comprising: operating an intermediate and final operation (operation only once) in order to complete the operation in the serial stream of a thread. A plurality of parallel streams created thread, the main advantage Fork / Join framework JDK7 split task and to speed up processing. Compared serial flow, parallel flow can greatly improve the degree of efficiency of the program

5: Optional substituents null

6: The new log and time, can be used instead of Date LocalDateTime instead of Instant Calendar DateTimeFormatter instead of SimpleDateFormat

7: CompletableFuture: CompletableFuture provides a very powerful extensions Future can help us simplify the complexity of asynchronous programming, and provides the ability to functional programming, can handle calculations callback way, but also provides conversion and combination CompletableFuture Methods.

8: element space is permanently removed Generation (PermGen) (Metaspace) instead of the configuration: -XX: MetaspaceSize = 8m -XX: MaxMetaspaceSize = 80m replaced -XX: PermSize = 10m -XX: MaxPermSize = 10m

lambda

JDK8 biggest feature should be none other than the non-lambda!

IDEA tool automatically prompts:

lambda syntax structure:
    Complete Lambda expressions consists of three parts: the parameter list, the arrow declaration;

(Type1 param1, Type2 param2, ..., TypeN paramN) -> {  statment1;  statment2;  //.............  return statmentM;}

Most cases, the compiler can be inferred from the parameters of the context type of the lambda expression, the parameters can be omitted:

(param1,param2, ..., paramN) -> {  statment1;  statment2;  //.............  return statmentM;}

When the number of only one lambda expression parameter may be omitted parentheses:

param1 -> {  statment1;  statment2;  //.............  return statmentM;}

When the lambda expression contains only one statement, you can omit the semicolon braces, return and the end of the sentence:

param1 -> statment

Where and how to use Lambda? ? ? ?

Lambda expressions you can use in functional interfaces above.

Note: JDK defines many now function interface, you can also define the interface actually do as an expression of the return, but directly used in most cases as defined JDK to be used.

Java SE 7 functions already present in the interface:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.util.concurrent.Callable
  • java.io.FileFilter
  • java.beans.PropertyChangeListener

In addition, Java SE 8 adds a new package: java.util.function, it contains commonly used interface functions, for example:

    Predicate – receiving the object and returns a boolean T

    Consumer – receiving the object T, does not return value

    Function – receiving the object T, the object returns R

    Supplier – T provides an object (e.g. plant) does not receive a value

Just look at a few:

The default method

Java 8 introduces new language features – the default method (Default Methods).

Default methods enable new functionality to be added to the interfaces of libraries and ensure binary compatibility with code written for older versions of those interfaces.

The default method allows you to add new functionality to an existing library interfaces, and to ensure binary compatibility with code written using an older version of the interface.

The default method is a method in the interface before adding the signature implementation method default keyword.

Why should there be a default method

Before java 8, the degree of coupling between the interface and its implementing class is too high (tightly coupled), when it is desired is a method for adding an interface, all classes must be followed to achieve the modification. The default way to solve this problem, it can add new methods to the interface, and will not undermine the achievement of the existing interface. This lambda expression as an important feature of java 8 languages ​​and comes as an upgrade older interfaces and maintain backward compatibility (backward compatibility) provides a way.

The forEach method is the default method jdk 1.8 interface to the new, precisely because of the introduction has been the default method, it will not because the Iterable interface has been added forEach method will need to modify the implementation class all Iterable interface.

Reference method (Method references)

If a Lambda expression simply call the method, it can be accomplished by the method of reference, use the reference code more readable in this case.

Method reference syntax:

A reference target placed on the front :: separator, method name on the back.

names2.forEach(System.out::println);//1
names2.forEach(s->System.out.println(s));//2

System.out’s method println lambda expression is only the second line of code calls the method call, so you can use the method reference written to System.out :: println.

The method of the referenced kind (Kinds of method references)

There are many methods cited, their syntax is as follows:

    Static method references: ClassName :: methodName

    Instance method on an instance reference: instanceReference :: methodName

    Examples of the method of the parent class references: super :: methodName

  • Examples of the method of the type cited: ClassName :: methodName

    NOTE: String :: toString equivalent to the lambda expression (s) -> s.toString ()
                Here less readily appreciated, instances to be invoked by the subject method, the first parameter corresponding to a reference method Lambda, Lambda will be subject example method call.

  • Constructor reference: Class :: new

  • Array references constructor: TypeName [] :: new

Personal understanding: reference method, plainly, with better, can not, if you can try to use! ! !

Stream

Stream 8 Java is enhanced in the collection (Collection) the object function, it focuses on the collection of various objects is very convenient and efficient polymerization operation (aggregate operation), or mass data operations (bulk data operation). Lambda expressions Stream API by means of the same emerging, which greatly improves the efficiency of programming and program readability. At the same time it provides both serial and parallel modes aggregation operation, concurrency model can take advantage of multi-core processors, using fork / join and split task in parallel to accelerate the process. Usually write parallel code is difficult and error-prone, but using Stream API without writing a single line of multi-threaded code, you can easily write high-performance concurrent programs.

    Stream is not a collection of elements, it is not a data structure of the data is not saved, it is about algorithms and calculations, it is more like an advanced version of Iterator.

    Stream like an iterator (the Iterator), unidirectional, not reciprocating, data can only be traversed once traversed once after exhausted, like water flows from the front, gone.

    And another difference is that the iterator, Stream parallel operation, only imperative iterators, the serialization operation.

The operation of the stream is divided into three categories.

    Create a stream

    Intermediate operations (intermediate operations) [no termination operation is not performed]

    Terminate the operation (terminal operations):

Further intermediate operation flow returns. It can be programmed with a chain. The form continues to call. In the absence of termination of the operation, intermediate operation is not performed.

Terminating operation of the flow does not return, but returns the result (such as the return void- only System.out output, such as the total number of return int, returns a collection list, etc.)

E.g:

Creating streams

Create a stream, call the normal stream 3 ways

    Stream interface through static factory method

  • By Arrays method

  • By default interface method Collection

//通过Stream接口的静态工厂方法
Stream stream = Stream.of("hello", "world", "hello world");

String[] strArray = new String[]{"hello", "world", "hello world"};
//通过Stream接口的静态工厂方法
Stream stream1 = Stream.of(strArray);

//通过Arrays方法
Stream stream2 = Arrays.stream(strArray);

List list = Arrays.asList(strArray);
//通过Collection接口的默认方法
Stream stream3 = list.stream();

Essentially StreamSupport.stream.

The method of obtaining a parallel flow through the default interface Collection.

Or obtaining a parallel stream by calling parallel flow stream

Only you need to call the parallel streams of sequential method can turn it into a sequential stream

Intermediate operation

Termination of operation

Parallel flow

ParallelStream method by calling the set of collected source into a parallel stream. It is a parallel stream of data into a plurality of contents
    Blocks, and each block of data flow processing are represented by different threads. This way, you can automatically assign all core to multi-core processors for a given operating workload, so that they are busy.

Parallel streams with threads is from where? How many? How to customize this process it?

Internal parallel streams using the default ForkJoinPool, it is the default number of threads is the number of your processor, this value is obtained from Runtime.getRuntime (). Available Processors (). But you can change the parallelism through the system thread pool size property java.util.concurrent.ForkJoinPool.common, as follows:
    System.setProperty ( “java.util.concurrent.ForkJoinPool.common.parallelism”, “12”);
    This is a global setting, so it will affect all of the parallel stream code. Conversely, there can not be designed for a
    Parallel flow designation value. In general, let ForkJoinPool size is equal to the number of processors is a good default value,
    Unless you have a good reason, otherwise we strongly recommend that you do not modify it

Parallel test sequence and flow velocity

//Sequential Sort, 采用顺序流进行排序
    @Test
    public void sequentialSort(){
        long t0 = System.nanoTime();

        long count = values.stream().sorted().count();
        System.err.println("count = " + count);

        long t1 = System.nanoTime();

        long millis  = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
        System.out.println(String.format("sequential sort took: %d ms", millis));
        //sequential sort took: 1932 ms

    }

    //parallel Sort, 采用并行流进行排序
    @Test
    public void parallelSort(){
        long t0 = System.nanoTime();

        long count = values.parallelStream().sorted().count();
        System.err.println("count = " + count);

        long t1 = System.nanoTime();

        long millis  = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
        System.out.println(String.format("parallel sort took: %d ms", millis));
        //parallel sort took: 1373 ms 并行排序所花费的时间大约是顺序排序的一半。
    }

Misuse flow

class Accumlator{
    public long total = 0;

    public void add(long value) {
        total += value;
    }
}


public class ParallelTest {
    public static void main(String[] args) {
        //错误使用并行流示例
        System.out.println("SideEffect parallel sum done in :" + measureSumPerf(ParallelTest::sideEffectParallelSum, 1_000_000_0) + "mesecs");
        System.out.println("=================");
        //正确应该这样的
        System.out.println("SideEffect  sum done in :" + measureSumPerf(ParallelTest::sideEffectSum, 1_000_000_0) + "mesecs");
    }

    //错误使用并行流
    public static long sideEffectParallelSum(long n) {
        Accumlator accumlator = new Accumlator();
        LongStream.rangeClosed(1, n).parallel().forEach(accumlator::add);
        return accumlator.total;
    }

    //正确使用流
    public static long sideEffectSum(long n) {
        Accumlator accumlator = new Accumlator();
        LongStream.rangeClosed(1, n).forEach(accumlator::add);
        return accumlator.total;
    }

    //定义测试函数
    public static long measureSumPerf(Function adder, long n) {
        long fastest = Long.MAX_VALUE;
        //迭代10次
        for (int i = 0; i < 2; i++) {
            long start=System.nanoTime();
            long sum = adder.apply(n);
            long duration=(System.nanoTime()-start)/1_000_000;
            System.out.println("Result: " + sum);
            //取最小值
            if (duration < fastest) {
                fastest = duration;
            }
        }
        return fastest;
    }

}

Nature of the problem that total + = value; it is not atomic, invoked in parallel when it changes state variable shared by multiple threads object, resulting in an error in the use of parallel streams need to avoid such problems occur!

Question: What are the normal results, but slower than in the case of parallel streams sequential flow of it? ? ?

Update shared variables in parallel flow, if you join the synchronized competition will likely find the thread offset the performance of parallel improvements brought about!

FindFirst particular limit and the like depending on the operation sequence of elements, which are performed on very large expense of parallel streams

A small amount of data, select the parallel flow it is almost never a good decision. The benefits of parallel processing elements are also a few not worth the extra cost due to parallelization.

NOTE: Wait sort or distinct operation takes a stream, and then generate a stream (intermediate operations), when the flow sort and remove duplicates from the data collection needs to know all, if a large set of data may be a problem (if the data is large, have put a memory, the memory is not enough will OOM).

Using a parallel flow or sequential flow should be tested, and measuring the pressure, if the parallel streams under normal circumstances, to enhance the efficiency of selection of parallel streams, if the order of selection sequence flow stream quickly.

Asynchronous functional programming CompletableFuture

The reason the introduction of CompletableFuture

Future models of the shortcomings

    While Future can achieve access to asynchronous execution result of the demand, but it does not provide a mechanism to notice, we do not know when Future completed.

    Either use blocks, waiting for the results of future returns at the local future.get (), then it is a synchronous operation. Either use isDone () Future determine whether the polling is completed, so that consumes CPU resources.

Limitations Future interface

future interfaces can build asynchronous applications, but still has its limitations. It is difficult to directly express dependencies between the plurality of Future results. The actual development, we often need to achieve the following objectives:

    The two asynchronous computation into one - two mutually independent asynchronous computation, while dependent on the first and second
            A result of.

    Future collection waiting all tasks are completed.

    Future collection only wait for the fastest end of the task is completed (likely because they are trying different ways to calculate the same
            A value), and returns its result.

    Future complete a task performed programmatically (i.e., manually set an asynchronous mode operation results).

    Future respond completion event (that is, when the completion Future events will be notified and can use the Future
            Result of the calculation to the next step, the result is not simply wait for the blocking operation)

The new CompletableFuture will make this possible.

CompletableFuture provides four static method used to create CompletableFuture objects:

The method of the parameters and return values ​​differ.

. There are a lot of methods, after the return of the chain can be programmed CompletableFuture form continues to call, a call is not the last return CompletableFuture introduction, and operation of the intermediate flow inside the operation - to terminate the operation.

date

/**
     * 可以使用Instant代替Date
     * LocalDateTime代替Calendar
     * DateTimeFormatter代替SimpleDateFormat
     */

    public static void main(String args[]) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now.format(formatter));

        //10分钟前
        String d1 = now.minusMinutes(10).format(formatter);
        //10分钟后
        String d2 = now.plusMinutes(10).format(formatter);

        System.out.println(d1);
        System.out.println(d2);


        LocalDateTime t5 = LocalDateTime.parse("2019-01-01 00:00:00", formatter);

        System.out.println(t5.format(formatter));


    }

JVM aspects of change

In addition to the permanent-generation (the PermGen) is replaced element space (Metaspace) Configuration: -XX: MetaspaceSize = 8m -XX: MaxMetaspaceSize = 80m replaced -XX: PermSize = 10m -XX: MaxPermSize = 10m

Optional replaced with a null

Optional object creation

1. Create an empty object

Optional optStr = Optional.empty();

The above sample code calls empty () method creates an empty Optional type objects.

2, create objects: NOT NULL
    Optional is provided a method of () is used to create a non-empty object, this method requires the incoming parameters can not be empty, otherwise throw NullPointException, examples are as follows:

Optional optStr = Optional.of(str);  // 当str为null的时候,将抛出NullPointException

3, create objects: Allow null
    If the incoming parameters can not be determined whether the possibility of the presence of a null value, it is possible () method to create the object with the ofNullable Optional, if the parameter is null, a null object is created. Examples are as follows:

Optional optStr = Optional.ofNullable(str);  // 如果str是null,则创建一个空对象

Common method

String str = null;

len = Optional.ofNullable(str).map(String::length).orElse(0); //不会报NullPointerException

如果读完觉得有收获的话,欢迎点赞、关注、加公众号 [匠心零度] ,查阅更多精彩历史!!!

Leave a Reply