JDK16 será lançado em breve, você está pronto? JDK8 novo recurso Lambda

      Os anos são silenciosos e os anos são sólidos. 2020 não é fácil para ratos de verdade e 2021 girará o mundo.

      Quando nossos desenvolvedores e a maioria das empresas ainda estiverem no JDK8, o JDK16 será lançado em breve. Você está pronto?

Como desenvolvedor, sou como todo mundo. Realmente não consigo acompanhar, nem consigo acompanhar a velocidade das atualizações do jdk, mas isso nos afetará? A resposta é não. Atualmente, muitas grandes empresas tradicionais estão presas nas versões convencionais do jdk6, jdk7, jdk8 e jdk9. Portanto, para nós, não é necessário atualizar e aprender o jdk16 por enquanto. É claro que a situação específica se baseia em suas próprias necessidades e você pode aprender se precisar. Isso não afetará seu trabalho por enquanto e talvez você não aprenda imediatamente. É claro que, como programadores, precisamos aprender com frequência.Não há limites para o aprendizado e aprenderemos enquanto vivermos. Se você tem um sonho, persiga-o. Mesmo se falhar, você não tem culpa. Então, aqui, o blogger não apresentará o jdk16, o blogger aqui apresenta principalmente as características de conhecimento do jdk8.

1. Introdução aos novos recursos do JDK8

  • Velocidade mais rápida: otimização de algoritmos (como HashMap), otimização da estrutura de memória subjacente (mudando a área permanente PremGen em MetaSpace)
  • Menos código (novas expressões de sintaxe Lambda adicionadas)
  • API de fluxo poderoso
  • Parcial para paralelo
  • Maximize a redução de exceções de ponteiro nulo
    Dicas opcionais : A
    área permanente pertence ao heap do heap (antes de jdk1.7, o heap é dividido em duas áreas: área de coleta de lixo e área permanente); e o meta espaço é armazenado na memória física

2. Idéias de programação funcional

  • Em matemática, função refere-se a um determinado valor de entrada, por meio de um conjunto de esquemas de cálculo e, finalmente, fornece o valor do resultado. Isso é fazer algo com alguma coisa.
  • Orientado a objetos enfatizou demais que algo deve ser feito na forma de objetos. (Atribuir importância ao processo de fazer as coisas)
  • A programação funcional enfatiza "o que fazer, não de que forma fazer". (Preste atenção aos resultados de fazer as coisas)

3. Princípios básicos da programação Lambda

3.1 Interface funcional

Antes de aprender Lambda, você precisa entender a interface funcional. Interface
funcional: adequada para cenários de programação funcional (expressões Lambda). Há um e apenas um método abstrato na interface, e a anotação FunctionalInterface precisa ser adicionada. O
código de amostra é do seguinte modo:

@FunctionalInterface
interface Conver{
	void fun();
}

3.2 Formato e descrição da expressão Lambda

O formato padrão da expressão Lambda é: (nome do parâmetro do tipo de parâmetro) -> {declaração de código}
descrição:

  • A sintaxe entre parênteses é consistente com a lista de parâmetros de método tradicional
  • -> é um formato gramatical recém-introduzido, que representa uma ação de apontar, indicando que o parâmetro antes do parêntese é usado na instrução de código no seguinte {}
  • A sintaxe entre chaves é basicamente consistente com os requisitos do corpo do método tradicional. Na verdade, é uma reescrita do único método abstrato na interface funcional

 

3.3 Lambda omitido formato

Lambda enfatiza "o que" em vez de "como", portanto, qualquer informação que possa ser derivada do contexto pode ser omitida.
As regras de omissão são as seguintes:

  • Os tipos de parâmetros entre parênteses podem ser omitidos;
  • Se houver apenas um parâmetro entre parênteses, os parênteses podem ser omitidos;
  • Se houver uma e apenas uma instrução entre colchetes, você pode omitir as chaves, a palavra-chave return e o ponto-e-vírgula de instrução, independentemente de haver um valor de retorno.

3.4 Exemplo de código

1) Sem parâmetros e sem valor de retorno

import org.junit.Test;
public class demo01 {
    @Test
    public void demo01(){
        //匿名内部类写法
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System.out.println("多线程任务1");
            }
        };
        new Thread(task).start();

        //Lambda写法
        new Thread(()->{System.out.println("多线程任务2");}).start();
        //{}里面只有一条语句,可以省略{}和;
        new Thread(()->System.out.println("多线程任务3")).start();
    }
}

 

2) Existem parâmetros e valores de retorno

//有参有返回值
//有参有返回值
@FunctionalInterface
public interface addSum {
    int sum(int a,int b);
}

 

package com.demo.lambda.day03;

import org.junit.Test;

public class LambdaAddSumDemo {
    @Test
    public void demo02() {
        //需求:求两个整数和
        //int result = addSum(10,20,(a,b)->{return a+b;});
        //可优化为下面代码
        int result = sum(10,20,(a,b)->a+b);
        System.out.println(result);
    }

    //两个int类型进行处理
    public int sum(int a,int b,addSum c){
        return c.sum(a,b);
    }
}

3) Parâmetros e tipos de valor de retorno são tipos de interface funcional

package com.demo.lambda.day03;
import org.junit.Test;
import java.util.Arrays;
import java.util.Comparator;

public class demo03 {
    @Test
    public void demo03() {
        //需求1:执行1个线程任务
        startThread(()->System.out.println("多线程"));

        //需求2:将数组按照由小到大顺序排序
        String[] arr = {"c","a","d","b"};
        Arrays.sort(arr,compara());
        System.out.println(Arrays.toString(arr));
    }

    //参数为函数式接口,执行1个线程操作
    public void startThread(Runnable target){
        new Thread(target).start();
    }

    //返回值类型为一个函数式接口,返回一个比较器对象
    public Comparator<String> compara(){
        return (a,b)->a.compareTo(b);
    }

}

3.5 Execução atrasada do Lambda

Depois que alguns códigos de cena são executados, os resultados podem não ser usados, o que causa perda de desempenho. Lambda tem as características de execução atrasada, o que pode resolver bem este problema.
O código de referência é o seguinte:

package com.demo.lambda.day03;

import org.junit.Test;

public class LambdaStringDemo {
    @Test
    public void demo04() {
        String msg1 = "hello";
        String msg2 = "world";
        //不论level,在调用log方法的时候,后面的参数一定要进行拼接操作
        log("2",msg1+msg2);

        //只有当level符合条件,才会去调用append方法,才会执行Lambda
        newLog("1",()->msg1+msg2);
    }

    //记录日志
    public void log(String level,String msg){
        if("1".equals(level)){
            System.out.println(msg);
        }
    }

    public void newLog(String level,MessageBuilder mb){
        if("1".equals(level)){
            System.out.println(mb.append());
        }
    }
}

 

4. Programação Lambda avançada

Interface funcional definida publicamente O
pacote de funções foi fornecido desde jdk1.8. Este pacote fez uma definição pública para a interface funcional que os usuários podem fazer
. Existem quatro interfaces principais:

  1. Interface funcional: Função <T, R>
    é um
    método abstrato de um método que recebe um parâmetro do tipo T e retorna um resultado do tipo R. Método abstrato: R apply (T t)
    Método padrão: andEntão o
    código de amostra é o seguinte:
package com.demo.lambda.day03;

import org.junit.Test;

import java.util.function.Function;

public class demo5 {
    @Test
    public void functionTest() {
        int num = fun("100",s->Integer.parseInt(s) );//字符串转成int类型
        System.out.println(num);
        //先将字符串转成int,再*10
        int result = method("5", s->Integer.parseInt(s), a->a *= 10);
        System.out.println(result);
    }

    //用于字符串处理
    public Integer fun(String s, Function<String,Integer> fun){
        return fun.apply(s);
    }

    //andThen:先执行一次apply操作,然后将第一次执行apply操作后获得的返回值作为参数再执行一次apply操作
    public int method(String s, Function<String,Integer> one,Function<Integer,Integer> two){
        return one.andThen(two).apply(s);
    }
}

2. Interface do consumidor: O
tipo de método correspondente de Consumidor <T> deve receber um parâmetro sem um valor de retorno
Método abstrato: void aceitar (T t)
Método padrão: eEntão o
código de amostra é o seguinte:

package com.demo.lambda.day03;
import org.junit.Test;
import java.util.function.Consumer;
public class demo6 {
    @Test
    public void consumerTest(){
        shopping(12345, m->System.out.println("花了"+m+"元买了包包"));
        //将"hElLo"转成大写输出,其次再转成小写输出
        fun("hElLo",s->System.out.println(s.toUpperCase()),
                s->System.out.println(s.toLowerCase()));
    }

    //花钱购物
    public void shopping(double money,Consumer<Double> con){
        con.accept(money);
    }

    //andThen:使用提供的参数执行两次操作
    public void fun(String str, Consumer<String> one, Consumer<String> two){
        one.andThen(two).accept(str);
    }

}

3. Interface de fornecimento: Fornecedor <T>
O tipo de método correspondente a esta interface não aceita parâmetros, mas fornece um valor de retorno
Método abstrato: O
código de amostra T get () é o seguinte:

package com.demo.lambda.day03;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;
public class demo7 {
    @Test
    public void supplierTest(){
        //获取10个0~99之间的随机数
        List<Integer> list = getList(10, ()->new Random().nextInt(100));
        System.out.println(list);
    }

    //获取指定个数的Integer集合
    public List<Integer> getList(int count, Supplier<Integer> sup){
        List<Integer> list = new ArrayList<>();
        for(int i=0;i<count;i++){
            list.add(sup.get());
        }
        return list;
    }

}

4. Interface de asserção: Predicado <T>
O método correspondente desta interface é receber um parâmetro e retornar um tipo booleano
Método abstrato: teste booleano (T t)
Método padrão: e (e), ou (ou), negar ( não)
O código de amostra é o seguinte: 

package com.demo.lambda.day03;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class demo8 {
    @Test
    public void predicateTest(){
        List<String> list = Arrays.asList("Tom","Jerry","Tony");
        List<String> nl = filterList(list, s->s.startsWith("T"));//将所有以“T”开头的字符串放入集合中
        System.out.println(nl);

        //判断一个字符串既包含"H",又包含"O"
        boolean bool = andFun(s->s.contains("H"),s->s.contains("O"),"HelloOpen");
        System.out.println(bool);

        //判断一个字符串中是否含有"H"或者"O"
        bool = orFun(s->s.contains("H"),s->s.contains("O"),"HelloOpen");
        System.out.println(bool);

        //对给定操作进行非判定
        bool = negateFun(s->s.length()<5,"helloworld");
        System.out.println(bool);
    }

    //将满足条件的字符串放入集合中
    public List<String> filterList(List<String> list, Predicate<String> pre){
        List<String> nl = new ArrayList<>();
        for(String s:list){
            if(pre.test(s)){
                nl.add(s);
            }
        }
        return nl;
    }

    //and
    public boolean andFun(Predicate<String> one,Predicate<String> two,String s){
        return one.and(two).test(s);
    }

    //or
    public boolean orFun(Predicate<String> one,Predicate<String> two,String s){
        return one.or(two).test(s);
    }

    //negate
    public boolean negateFun(Predicate<String> pre, String s){
        return pre.negate().test(s);
    }

}

Anexo: algumas outras interfaces comumente usadas

Nota: Documentos citados de referência:

https://blog.csdn.net/u010572176/article/details/104393869

Acho que você gosta

Origin blog.csdn.net/qq_30764991/article/details/113056903
Recomendado
Clasificación