java8 new features study notes

Java8 new features study notes

1 main content

  1. Lambda expressions
  2. Functional Interface
  3. And references cited constructor method
  4. Stream API
  5. The default interface methods, and static methods
  6. The new date and time API
  7. Other new features

2 Simple

  1. Faster modifying the underlying list Hash algorithm, HashMap, HashSet (from the previous array plus a listing -> + List Array / red-black tree), in addition to the added speed, ConcurrentHashMap (CAS Algorithm)
  2. Code more concise (Lambda expressions)
  3. Powerful StreamAPI (operational data collection is very convenient)
  4. Parallel to facilitate
  5. Optional null pointer maximize reduction vessel Classes

3 Lambda Expressions

Lambda is an anonymous function, Lambda expressions can be understood as a piece of code can be transmitted (the same as the code for transmitting image data). You can write simpler, more flexible code. As a more compact code style, the Java language skills has improved.

Case:


  //原来的匿名内部类
  public void test1(){
      //比较器 
        Comparator<Integer> com=new Comparator<Integer>(){
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        };
    }

    //使用 Lambda表达式
    public void test2(){
        //x,y为传入的参数 形参,Integer.compare(x,y) 为方法内内容
        Comparator<Integer> com=(x,y)->Integer.compare(x,y);
    }

As shown, the new syntax, the code more compact, ->referred Lambda operator, into left and right portions of the Lambda:

Left: specify all the parameters required for Lambda expressions

Right: the body designated Lambda, Lambda expressions function that is to be performed

The syntax is divided into three cases

  1. A syntax: no arguments and returns no value, Lambda body simply a statement

    Runable run = ()->System.out.println("执行的语句")(Create a task thread)

  2. Two syntax: Lambda requires an argument

    Comsumer com = (args)->System.out.println(args)

    If only one parameter can not bracket args->System.out.println(args)(Comsumer as a function of programming interfaces, consumption patterns, receiving a parameter, no return value)

  3. Three syntax: Lambda takes two parameters and returns a value

  4. Three syntax: Lambda requires three parameters,

    BinaryOperato bin =(x,y)->{ return x+y ;}; (Binary interface function, receives two numbers, returns the number of a same type)

    If only one executable statement, you can omit return and braces BinaryOperato bin =(x,y)-> x+y

The above parameter brackets, not the type of write parameters, this is because the compiler can generic context, methods, inferred type, which is called "type inference."

4 Functional Interface

Contains only an abstract interface method, called a function interface.

In the grammar rules Lambda above, the expression on the right is the actual content of the operation is to achieve the interface, but if the interface has two abstract classes, the content of this operation, what should belong to which, therefore, Lambda expressions , there must be support functional interface.

You can create objects of the interface via Lambda expressions. (Lambda expressions thrown if a subject exception, the exception needs to be declared on the abstract methods of target interface).

We can use on any function interface @FunctionalInterface notes, doing so can check whether it is a functional interface, while javadoc will also include a statement that this interface is a functional interface.

Lambda expressions passed as a parameter: To Lambda expressions passed as a parameter, the parameter type received Lambda expressions must be compatible with the type of Lambda expression of functional interface.
Case: a definition of their function interface

@FunctionalInterface
public interface MyFun {
    public Integer getValue(Integer num);
}

Case: the definition of a function interface, and used as a method of parameter transfer

//需求:对一个数进行运算
    @Test
    public void  test6(){
        //只一个函数式接口,就可以进行多种运算
        Integer num=operation(100, (x)->x*x);
        System.out.println(num);

        System.out.println(operation(200, (y)->y+200));
    }

    public Integer operation(Integer num,MyFun mf){
        return mf.getValue(num);
    }

Case: Call Collections.sort () method to compare two Employee through custom ordering (older than press, of the same age than by name), using a Lambda passed as a parameter.

List<Employee> employees=Arrays.asList(
            new Employee("张三",18,9496.2),
            new Employee("李四",52,2396.2),
            new Employee("王五",56,996.2),
            new Employee("赵六",8,94.2)
    );

    @Test
    public void test1(){
        //使用Lambda 可以轻松的定义比较规则,
         Collections.sort(employees, (e1,e2)->{
             if(e1.getAge()==e2.getAge()){
                 return e1.getName().compareTo(e2.getName());
             }else{
                 return Integer.compare(e1.getAge(), e2.getAge());
             }
         });
    }

For convenience we use Lambda expressions, java gives us a built-in function interface,

Built four interface functions java

  1. Consumer : Consumer Interface

    void accept(T t);

  2. Supplier : Supplying Interface

    T get();

  3. Function <T, R>: Function Interface

    R apply(T t);

  4. Preicate : Assertion Interface

    boolean test(T t);

Other interfaces:

5 and references cited constructor method

There are three main methods cited syntax:

:: Object instance method name

:: class static method name

:: class instance method names

note:

1, the body Lambda parameter list and calling a method return type, a list of functions to interface with the abstract functions and methods consistent with the return type!

2, if the first parameter is a parameter list Lambda caller example of a method, and the second parameter is a parameter example of a method, the

(X, y) -> x.equals (y) can be written String :: equals ClassName :: method may be used

public class TestMethodRef { 

    //对象::实例方法名
    @Test
    public void test1(){
        PrintStream ps1=System.out;   //打印流对象
        Consumer<String> con=(x)->ps1.println(x);
        //可以写成下面的样子
        PrintStream ps=System.out;
        Consumer<String> con1=ps::println;//相当于上面,引用了ps对象的println()方法
        Consumer<String> con2=System.out::println;
        
    }

    @Test
    public void test2(){
        final Employee emp=new Employee();  //匿名内部类中引用外部的对象,该对象必须为final
        Supplier<String> sup=()->emp.getName();//代替匿名内部类 (jdk1.8后 引用的对象就算没有显式           的加final ,也可以正常使用了,但这个只是语法糖,其底层还是会自动加上final,如果后面对其改变,会           报错)
       
        Supplier<Integer> sup2=emp::getAge; // 引用emp对象的方法,实现抽象方法,进行对外供给
        Integer num=sup2.get();
    }

    //类::静态方法名
    @Test
    public void test3(){
        Comparator<Integer> com=(x,y)->Integer.compare(x,y);
        Comparator<Integer> com1=Integer::compare;//引用静态方法
    }

    //类::实例方法名
    @Test
    public void test4(){
        BiPredicate<String,String> bp=(x,y)->x.equals(y);
        BiPredicate<String, String> bp2=String::equals; //第一个参数是调用者,第二个参数是实参
    }

Constructor reference:

Format: ClassName :: new

Combined with the interface function, the function interface is compatible with automatic methods. The constructor method may be defined by reference to the assignment, configuration and parameter list for the interface parameter list of abstract methods consistent

//构造器引用
    @Test
    public void test5(){
        Supplier<Employee> sup=()->new Employee();
        //构造器引用方式
        Supplier<Employee> sup2=Employee::new;//使用无参构造器
        Employee emp=sup2.get(); //引用Employee构造器进行供给
        //带参的构造器
        Function<Integer,Employee> fun2=(x)->new Employee(x);
        BiFunction<String,Integer,Employee> bf=Employee::new;//也这么写,抽象方法中的参数类型会自动                                                          匹配相对应的构造器
    }

Array reference:

References to create an array of ways


    //数组引用
    @Test
    public void test6(){
        Function<Integer,String[]> fun=(x)->new String[x];
        String[] strs=fun.apply(10);
        System.out.println(strs.length);

        Function<Integer,String[]> fun2=String[]::new;
        String[] str2=fun2.apply(20);
        System.out.println(str2.length);
    }
}

6 Stream Api

In Java8 have two of the most important changes.

The first is the Lambda expressions;

Another is the Stream API (java.util.stream. *).
Stream processing is a key abstractions Java8 collection, you can specify that you want it to be a set of operations can be performed very complex search, filtering and mapping data and other operations. Use Stream API to manipulate the data collection, similar to using a SQL database query execution. Stream API may be used to perform operations in parallel.

  • Stream does not own storage elements.
  • Stream does not change the source object. Instead, they will return the result of holding a new Stream.
  • Stream delay operation is performed. This means that they will only need to wait until the results of the implementation of the (superior performance)

Stream three-step operation

  • Stream create
    a data source (such as: collection, arrays), obtaining a stream
  • Intermediate operating
    a chain intermediate operation, the data processing of the data source
  • Terminate the operation (operation terminal)
    a termination operation, performing the intermediate operation chain, and produce results

Create a stream

  1. Via stream () or parallelStream () provides a set of methods in Collection

    default Stream <E> stream () : returns a sequence flow
    default Stream <E> parallelStream () : returns a parallel stream

  2. () Gets an array of flow through the static methods stream Arrays of tools

    static <T> Stream <T> stream (T [] array): Returns an array of the reception of any type of a stream of the type

    Overloads, capable of handling an array corresponding to the basic types:

    public static IntStream stream(int[] array)
    public static LongStream stream(long[] array)
    public static DoubleStream stream(double[] array)

  3. of (), by displaying the value of a stream created by the Stream class static method. It can receive any number of parameters.

    public static <T> Stream <T> of (T ... values): receive any number of directly create a type value of a stream of the type

  4. Create an unlimited stream

    You can use the static method Stream.iterate () and Stream.generate (), create an infinite stream.

  5. 迭代
    public static< T> Stream< T> iterate(final T seed, final UnaryOperator< T> f)
    生成
    public static< T> Stream< T> generate(Supplier< T> s)

Here is the case:

//创建Stream
    @Test
    public void test1(){
        //1.可以通过Collection 系列集合提供的stream()或parallelStream()
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();

        //2.通过 Arrays 中的静态方法stream()获取数组流
        Employee[] emps=new Employee[10];
        Stream<Employee> stream2=Arrays.stream(emps);

        //3.通过Stream 类中的静态方法of()
        Stream<String> stream3=Stream.of("aa","bb","cc");

        //4.创建无限流
        //迭代
        Stream<Integer> stream4=Stream.iterate(0, (x) -> x+2);
        stream4.limit(10).forEach(System.out::println);

        //生成
        Stream.generate(() -> Math.random())
              .limit(5)
              .forEach(System.out::println);
    }

Intermediate operation

A plurality of intermediate operations may be joined to form a pipeline, the pipeline operation unless the terminating trigger, as otherwise the operation does not perform any process! Upon termination of the disposable processing operation, a "lazy evaluation."

  1. Filtration and sliced

 //中间操作

    List<Employee> employees=Arrays.asList(
            new Employee("张三",18,9999.99),
            new Employee("李四",58,5555.55),
            new Employee("王五",26,3333.33),
            new Employee("赵六",36,6666.66),
            new Employee("田七",12,8888.88),
            new Employee("田七",12,8888.88)
            );

    //Steam对象执行中间操作时,会返回Steam对象,实现链式调用
 //内部迭代:迭代操作由 Stream API 完成
    @Test
    public void test1(){
        //中间操作:不会执行任何操作(没有终止操作)
        //过滤操作,过滤规则为传入的断言函数式接口来定义(本案例为年龄超过35岁的)
        Stream<Employee> stream=employees.stream()
                                .filter((e) -> e.getAge()>35 );
        //终止操作:一次性执行全部内容,即 惰性求值(执行这一句代码时,上面的中间操作才会执行)
        stream.forEach(System.out::println);
    }

    //外部迭代
    @Test
    public void test2(){
        Iterator<Employee> it=employees.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }

    @Test
 //limit中间操作 在找到指定的条数数后,会自动切断流的迭代
    public void test3(){//发现“短路”只输出了两次,说明只要找到 2 个 符合条件的就不再继续迭代
        employees.stream()
                 .filter((e)->{
                     System.out.println("短路!");
                     return e.getSalary()>5000;
                 })
                 .limit(2)
                 .forEach(System.out::println);
    }

    @Test
    public void test4(){
        employees.stream()
                 .filter((e)->e.getSalary()>5000)
                 .skip(2)//跳过前两个
                 .distinct()//去重,注意:需要Employee重写hashCode 和 equals 方法
                 .forEach(System.out::println);
    }
  1. Mapping

 @Test
    public void test5(){
        List<String> list=Arrays.asList("aaa","bbb","ccc","ddd");
        //将作用于其中每一个元素
        list.stream()
             .map((str)->str.toUpperCase())
             .forEach(System.out::println);

        employees.stream()
                 .map(Employee::getName)
                 .forEach(System.out::println);

     //将其中的每个元素都映射成一个流(该案例为把每个字符串变成字符集合的流)
        Stream<Stream<Character>> stream=list.stream()
                                             .map(TestStreamAPI2::filterChatacter);
        //遍历主流 ,取出其中每个流,再遍历每个流,得到每个字符
        stream.forEach((sm)->{
            sm.forEach(System.out::println);
        });

        System.out.println("------------------------");
     //将其中每个元素变成一个流后,并合并这些流,变成一个流,所有的元素在一起
        Stream<Character> sm=list.stream()
                                 .flatMap(TestStreamAPI2::filterChatacter);
        sm.forEach(System.out::println);
    }

    public static Stream<Character> filterChatacter(String str){
        List<Character> list=new ArrayList<>();
        for (Character ch : str.toCharArray()) {
            list.add(ch);
        }
        return list.stream();
    }

    @Test
    public void test6(){
        //map和flatMap的关系  类似于 add(Object)和addAll(Collection coll)
        List<String> list=Arrays.asList("aaa","bbb","ccc","ddd");
        List list2=new ArrayList<>();
        list2.add(11);
        list2.add(22);
        list2.addAll(list);
    }
  1. Sequence


the Java `` `
@Test
public void TEST7 () {
// default natural ordering
List list=Arrays.asList("ccc","bbb","aaa");
list.stream()
.sorted()
.forEach(System.out::println);

          System.out.println("------------------------");
        //按照自定义的排序规则
          employees.stream()
                   .sorted((e1,e2)->{
                       if(e1.getAge().equals(e2.getAge())){
                           return e1.getName().compareTo(e2.getName());
                       }else{
                           return e1.getAge().compareTo(e2.getAge());
                       }
                   }).forEach(System.out::println); 
      }
  ```

Termination of operation

The terminal will generate results from the pipeline flow. As a result, not a stream can be any value, for example: List, Integer, or even a void

  1. Find matches


List<Employee> employees=Arrays.asList(
            new Employee("张三",18,9999.99,Status.FREE),
            new Employee("李四",58,5555.55,Status.BUSY),
            new Employee("王五",26,3333.33,Status.VOCATION),
            new Employee("赵六",36,6666.66,Status.FREE),
            new Employee("田七",12,8888.88,Status.BUSY)
            );
    /*
     * 查找与匹配
     * 
     */

    @Test
    public void test1(){
        boolean b1=employees.stream()//allMatch-检查是否匹配所有元素(状态都为BUSY的)
                            .allMatch((e)->e.getStatus().equals(Status.BUSY));
        System.out.println(b1);//false

        boolean b2=employees.stream()//anyMatch-检查是否至少匹配一个元素(至少有一个是BUSY的)
                            .anyMatch((e)->e.getStatus().equals(Status.BUSY));
        System.out.println(b2);//true

        boolean b3=employees.stream()//noneMatch-检查是否没有匹配所有元素(一个都不是)
                            .noneMatch((e)->e.getStatus().equals(Status.BUSY));
        System.out.println(b3);//false

        //findFirst-返回第一个元素//Optional是Java8中避免空指针异常的容器类
        Optional<Employee> op=employees.stream()
                 .sorted((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary()))
                 .findFirst();
        System.out.println(op.get());//Employee [name=王五, age=26, salary=3333.33, Status=VOCATION]

        Optional<Employee> op2=employees.parallelStream()//findAny-返回当前流中的任意元素
                                        .filter((e)->e.getStatus().equals(Status.FREE))
                                        .findAny();
        System.out.println(op2.get());//Employee [name=赵六, age=36, salary=6666.66, Status=FREE]

        Long count=employees.stream()//count-返回流中元素的总个数
                            .count();
        System.out.println(count);//5

        Optional<Employee> op3=employees.stream()//max-返回流中最大值(比较规则可以定义,倒过来放)
                                        .max((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(op3.get());//Employee [name=张三, age=18, salary=9999.99, Status=FREE]

        Optional<Double> op4=employees.stream()//min-返回流中最小值
                                      .map(Employee::getSalary)
                                      .min(Double::compare);
        System.out.println(op4.get());//3333.33
    }
  1. Statute


/*
     * 归约(可以和map相结合使用)
     * reduce(T identity,BinaryOperator b) / reduce(BinaryOperator b)-可以将流中元素反复结合起来,得到一个值。
     */
    @Test
    public void test3(){
        List<Integer> list=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer sum=list.stream()//reduce(T identity,BinaryOperator b)
                        .reduce(0, (x,y)->x+y);//0为起始值
        System.out.println(sum);

        System.out.println("--------------------------");

        Optional<Double> op=employees.stream()//reduce(BinaryOperator b)//没有起始值,map返回可能为空,所以返回Optional类型
                                     .map(Employee::getSalary)
                                     .reduce(Double::sum);
        System.out.println(op.get());
    }
  1. collect

    Collector implement the interface method determines how convection do the collection (such as collecting the List, Set, Map). But Collectors utility class provides many static methods, you can easily create a common collector instance, specific methods and examples in the following table:



 /*
     * 收集
     * collect-将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法。
     */
    @Test
    public void test4(){
        List<String> list=employees.stream()
                                   .map(Employee::getName)
                                   .collect(Collectors.toList());
        list.forEach(System.out::println);

        System.out.println("----------------------------");

        Set<String> set=employees.stream()
                                 .map(Employee::getName)
                                 .collect(Collectors.toSet());
        set.forEach(System.out::println);

        System.out.println("----------------------------");

        HashSet<String> hs=employees.stream()
                                    .map(Employee::getName)
                                    .collect(Collectors.toCollection(HashSet::new));
        hs.forEach(System.out::println);

        System.out.println("----------------------------");

        //总和
        Long count=employees.stream()
                            .collect(Collectors.counting());
        System.out.println(count);

        //平均值
        Double avg=employees.stream()
                            .collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println(avg);

        //总和
        Double sum=employees.stream()
                            .collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println(sum);

        //最大值
        Optional<Employee> max=employees.stream()
                                        .collect(Collectors.maxBy((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println(max.get());

        //最小值
        Optional<Double> min=employees.stream()
                                      .map(Employee::getSalary)
                                      .collect(Collectors.minBy(Double::compare));
        System.out.println(min.get());

        System.out.println("----------------------------");

        //分组
        Map<Status,List<Employee>> map=employees.stream()
                                                .collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(map);//{FREE=[Employee [name=张三, age=18, salary=9999.99, Status=FREE], Employee [name=赵六, age=36, salary=6666.66, Status=FREE]], VOCATION=[Employee [name=王五, age=26, salary=3333.33, Status=VOCATION]], BUSY=[Employee [name=李四, age=58, salary=5555.55, Status=BUSY], Employee [name=田七, age=12, salary=8888.88, Status=BUSY]]}

        //多级分组
        Map<Status,Map<String,List<Employee>>> map2=employees.stream()
                                                            .collect( Collectors.groupingBy( Employee::getStatus,Collectors.groupingBy((e)->{
                                                                if(e.getAge()<=35){
                                                                    return "青年";
                                                                }else if(e.getAge()<=50){
                                                                    return "中年";
                                                                }else{
                                                                    return "老年";
                                                                }
                                                            }) ) );
        System.out.println(map2);//{FREE={青年=[Employee [name=张三, age=18, salary=9999.99, Status=FREE]], 中年=[Employee [name=赵六, age=36, salary=6666.66, Status=FREE]]}, VOCATION={青年=[Employee [name=王五, age=26, salary=3333.33, Status=VOCATION]]}, BUSY={青年=[Employee [name=田七, age=12, salary=8888.88, Status=BUSY]], 老年=[Employee [name=李四, age=58, salary=5555.55, Status=BUSY]]}}

        //分区
        Map<Boolean,List<Employee>> map3=employees.stream()
                                                 .collect(Collectors.partitioningBy((e)->e.getSalary()>8000));
        System.out.println(map3);//{false=[Employee [name=李四, age=58, salary=5555.55, Status=BUSY], Employee [name=王五, age=26, salary=3333.33, Status=VOCATION], Employee [name=赵六, age=36, salary=6666.66, Status=FREE]], true=[Employee [name=张三, age=18, salary=9999.99, Status=FREE], Employee [name=田七, age=12, salary=8888.88, Status=BUSY]]}

        System.out.println("--------------------------------");

        DoubleSummaryStatistics dss=employees.stream()
                                             .collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(dss.getSum());
        System.out.println(dss.getAverage());
        System.out.println(dss.getMax());

        System.out.println("--------------------------------");
        String strr=employees.stream()
                             .map(Employee::getName)
                             .collect(Collectors.joining(","));
        System.out.println(strr);//张三李四王五赵六田七
     }

Guess you like

Origin www.cnblogs.com/xjwhaha/p/11685614.html