Nuevas características de Java8: expresiones Lambda, interfaces funcionales, Stream API (notas)

1. expresión lambda

Lambda es una nueva característica de Java 8. El uso de Lambda puede reemplazar la implementación de una interfaz (interfaz de función) con un solo método abstracto, similar a una clase interna anónima.

1.1 Formato de sintaxis Lambda

()-> {
    
    }
  • (): Se utiliza para describir la lista de parámetros.
  • {}: se utiliza para describir el cuerpo del método y la declaración de ejecución. Se puede omitir cuando solo hay una declaración de ejecución o solo el valor de retorno.
  • -> :Operador lambda

1.2 Ejemplo de sintaxis básica de Lambda
para crear múltiples interfaces

public interface LambdaInterface {
    
    
    int test1();
}

@FunctionalInterface
public interface LambdaInterface1 {
    
    
    int test2(int a);
}

@FunctionalInterface
public interface LambdaInterface2 {
    
    
   int test3(int a,int b);
}

@FunctionalInterface
public interface LambdaInterface3 {
    
    
    void test4();
}

@FunctionalInterface
public interface LambdaInterface4 {
    
    
  void test5(int a);
}


@FunctionalInterface
public interface LambdaInterface5 {
    
    
   void test6(int a,int b);
}

clase de prueba

public class LambdaTest {
    
    
    public static void main(String[] args) {
    
    
        /**
         * 无参数,有返回值
         */

        //LambdaInterface test = () ->{return 200;};
        LambdaInterface test = () -> 200;
        int i2 = test.test1();
        System.out.println(i2);
        /**
         * 有单个参数,有返回值
         */
        //LambdaInterface1 test2 = (int a) ->{return a;};
        LambdaInterface1 test2 = a -> a;
        int i3 = test2.test2(200);
        System.out.println(i3);
        /**
         * 有多个参数,有返回值
         */
        //LambdaInterface2 test3 =(int a ,int b) -> {return a-b;};
        LambdaInterface2 test3 =(a,b) -> a-b;
        int i = test3.test3(20, 1);
        System.out.println(i);
        /**
         * 有参数,无返回值
         */
       // LambdaInterface4 test4 = a -> {System.out.println(a);};
        LambdaInterface4 test4 = a -> System.out.println(a);
        test4.test5(12);
        /**
         * 有多个参数,无返回值
         */
        //LambdaInterface5 test5 = (a, b) ->{System.out.println("a="+a+"  b="+b);};
        LambdaInterface5 test5 = (a, b) -> System.out.println(a+b);
        test5.test6(12,24);
        /**
         * 无参数,无返回值
         */
        LambdaInterface3 test6 = () -> System.out.println("无参数,无返回值!");
        test6.test4();
    }

}

Resultado de salida
Insertar descripción de la imagen aquí
1.3, referencia del método Lambda

Referencia de método: si el contenido del cuerpo de Lambda tiene métodos que se han implementado, podemos usar "referencia de método (que puede entenderse como una referencia de método que es otra forma de expresión de una expresión Lambda). Hay tres formatos de sintaxis principales: Objeto: : método
de creación de instancias
Nombre
Clase::nombre del método estático
Clase::nombre del método de instancia
Nota: 1. La lista de parámetros y el tipo de valor de retorno del método de llamada en el cuerpo de Lambda deben ser coherentes con la lista de funciones y el tipo de valor de retorno del método abstracto en la interfaz funcional! 2.
Si el primer parámetro en la lista de parámetros Lambda es el llamador del método de instancia y el segundo parámetro es el parámetro del método de instancia, puede usar ClassName::method

  //对象::实例方法名
    @Test
    public  void test1(){
    
    
        //Consumer<String> con1 =(x) -> System.out.println(x);
        Consumer<String> con = System.out::println;
        con.accept("adcdef");
    }
    //类::静态方法名
    @Test
    public void test2(){
    
    
      //Comparator<Integer> com = (x ,y) ->Integer.compare(x,y);

      Comparator<Integer> com1 = Integer::compare;
    }
    //类::实例方法名
    @Test
    public void test3(){
    
    
        //BiPredicate<String,String> bp =(x,y) -> x.equals(y);
        BiPredicate<String,String> bp =String::equals;
    }
    //数组引用
    @Test
    public void test4(){
    
    
        //Function<Integer,String[]> fun =(x) ->new String[x];
        Function<Integer,String[]> fun = String[]::new;
        String[] strs = fun.apply(10);
        System.out.println(strs.length);
    }

}

Resultado de salida
Insertar descripción de la imagen aquí
1.4, la referencia del método (constructor)
crea una clase de entidad

public class Person {
    
    
    public String name;
    public int age;

    public Person(){
    
    
        System.out.println("这是无参构造方法");
    }
    public Person(String name,int age){
    
    
        System.out.println("这里是有参构造");
        this.name=name;
        this.age=age;
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Crear interfaz

interface LambdaInterfaceTest{
    
    
    Person getPerson();
}
interface LambdaInterfaceTest1{
    
    
    Person getPerson(String name,int age);
}

clase de prueba


public class LambdaTest2 {
    
    
    public static void main(String[] args) {
    
    
        LambdaInterfaceTest test = ()-> new Person();
        test.getPerson();
        //构造方法的引用
        LambdaInterfaceTest test1 = Person::new;
        test1.getPerson();
        LambdaInterfaceTest1 test11 =Person::new;
        test11.getPerson("lzf",12);

    }
}

Resultados de salida
Insertar descripción de la imagen aquí

2. Interfaz funcional

1. El requisito previo para usar expresiones Lambda es que la interfaz debe ser una interfaz funcional
2. Una interfaz funcional (FunctionalInterface) es una interfaz que tiene uno y solo un método abstracto, pero puede tener múltiples métodos no abstractos.
3. Las interfaces funcionales se pueden convertir implícitamente en expresiones lambda.
4. Expresiones Lambda y referencias de métodos (en realidad, también se pueden considerar expresiones Lambda)
5. Utilice la anotación @FunctionalInterface

Cuatro interfaces de funciones principales integradas

public class Lambda5 {
    
    
    //Supplier<T>
    @Test
    public void test1(){
    
    
        List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100));
        for (Integer n:numList) {
    
    
            System.out.print(n+" ");
        }
    }
    //需求:产生指定个数的整数,并放入集合中
    public List<Integer> getNumList(int num, Supplier<Integer> sup){
    
    
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
    
    
            Integer n = sup.get();
            list.add(n);
        }
        return list;

    }
    @Test
    //Predicate<T>
    public void test2(){
    
    
        List<String> list = Arrays.asList("kzf","sdad","sdada","hwidh");
        List<String> strings = filterStr(list, (s -> s.length() > 3));
        for (String a:strings) {
    
    
             System.out.print(a+" ");
        }
    }
    //将满足条件的字符串,放入集合中
    public List<String> filterStr(List<String> list, Predicate<String> pre){
    
    
        List<String> list1 = new ArrayList<>();
        for (String a: list) {
    
    
            if(pre.test(a)){
    
    
                list1.add(a);
            }
        }
        return list1;
    }
    //Consumer<T> :处理字符串
    @Test
    public void test3(){
    
    
        nihao("dci",(m)-> System.out.println("你好"+m));
    }
    public void nihao(String name, Consumer<String> con){
    
    
        con.accept(name);
    }

    //Function<T,R>函数型接口:
    @Test
    public void test4(){
    
    
        String s = strHandler("\t\t\t你好我他", (str) -> str.trim());
        System.out.println(s);

    }
    public String strHandler(String str, Function<String,String> fun){
    
    
        return fun.apply(str);
    }
}

Resultados de salida

1. 22 30 82 84 54 49 62 38 55 2
2. sdad sdada hwidh
3. Hola dci
4. Hola yo, él

Algunas interfaces funcionales integradas en el sistema.

public class FunctionalInterface {
    
    
    public static void main(String[] args) {
    
    

        // Predicate<T>              :     参数是T 返回值boolean  
        // 在后续如果一个接口需要指定类型的参数,返回boolean时可以指向 Predicate
        //          IntPredicate            int -> boolean
        //          LongPredicate           long -> boolean
        //          DoublePredicate         double -> boolean

        // Consumer<T>               :      参数是T 无返回值(void)
        //          IntConsumer             int ->void
        //          LongConsumer            long ->void
        //          DoubleConsumer          double ->void

        // Function<T,R>             :      参数类型T  返回值R
        //          IntFunction<R>          int -> R
        //          LongFunction<R>         long -> R
        //          DoubleFunction<R>       double -> R
        //          IntToLongFunction       int -> long
        //          IntToDoubleFunction     int -> double
        //          LongToIntFunction       long -> int
        //          LongToDoubleFunction    long -> double
        //          DoubleToLongFunction    double -> long
        //          DoubleToIntFunction     double -> int

        // Supplier<T> : 参数 无 返回值T
        // UnaryOperator<T> :参数T 返回值 T
        // BiFunction<T,U,R> : 参数 T、U 返回值 R
        // BinaryOperator<T> :参数 T、T 返回值 T
        // BiPredicate<T,U> :  参数T、U  返回值 boolean
        // BiConsumer<T,U> :    参数T、U 无返回值

        /**
         * 常用的 函数式接口
         * Predicate<T>、Consumer<T>、Function<T,R>、Supplier<T>
         */
    }
}

3. API de transmisión

Varias formas de crear una transmisión

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

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

        //3.通过Arrays中的静态方法stream()获取数据流
        Person[] person = new Person[10];
        Stream<Person> stream1 = Arrays.stream(person);

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

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

Generar datos de prueba

  List<Person> personList = Arrays.asList(
            new Person("张三", 14),
            new Person("李四", 28),
            new Person("王五", 38),
            new Person("张三", 59),
            new Person("张三", 75),
            new Person("张三", 75),
            new Person("张三", 75)
    );

Filtrar y cortar


    //filter --接受Lambda,从流中排出某些元素
    @Test
    public void test1() {
    
    
        Stream<Person> stream = personList.stream()
                .filter((e) -> e.getAge() > 30);
        stream.forEach(System.out::println);
    }

    /**
     * 运行结果
     * Person{name='王五', age=38}
     * Person{name='张三', age=59}
     * Person{name='张三', age=75}
     * Person{name='张三', age=75}
     * Person{name='张三', age=75}
     */

    //limit--截断流,使其元素不超过给定数量
    @Test
    public void test2() {
    
    
        personList.stream()
                .filter((e) -> e.getAge() > 30)
                .limit(2)
                .forEach(System.out::println);
    }

    /**
     * 运行结果
     * Person{name='王五', age=38}
     * Person{name='张三', age=59}
     */

    //skip(n)跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与 limit(互补)
    @Test
    public void test3() {
    
    
        personList.stream()
                .filter((e) -> e.getAge() > 30)
                .limit(2)
                .skip(1)
                .forEach(System.out::println);
    }

    /**
     * 运行结果
     Person{name='张三', age=59}
     */

    //distinct --筛选,通过流所生成元素的hashCode()和equals()去除重复元素
    @Test
    public void test4() {
    
    
        personList.stream()
                .filter((e) -> e.getAge() > 30)
                .limit(2)
                .skip(1)
                .distinct()
                .forEach(System.out::println);
    }

    /**
     * 运行结果
     Person{name='张三', age=59}
     */


clasificar

 @Test
   @Test
    //自然排序
    public void test5(){
    
    
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        list.stream()
                .sorted()
                .forEach(System.out::println);
    }
    /**
     * 运行结果
     * 1
     * 2
     * 3
     * 4
     * 5
     */

Encontrar pareja

   //findAny()和findFist()获取第一条数据,如果没有就返回为空。
    @Test
    public void test6() {
    
    
        Person person = personList.stream()
                .filter((e) -> e.getAge() > 30)
                .limit(2)
                .findAny()
                .orElse(null);
        System.out.println(person);
    }

    /**
     * 运行结果
     * Person{name='王五', age=38}
     */

    //map(T -> R):使用map取出姓名(字符串)
    @Test
    public void test7(){
    
    
        personList.stream()
                .map(Person::getName)
                .forEach(System.out::println);
    }

    /**
     * 运行结果
     * 张三
     * 李四
     * 王五
     * 张三
     * 张三
     * 张三
     * 张三
     */

método de juicio

  • Determinar si hay un elemento en la colección List que contiene un elemento llamado Zhang San
  • Determine si todos los nombres de entidades en la colección Lista contienen el campo "Zhang".
  • Determine si hay un campo en la colección Lista que no contenga "Zhang".
@Test
    public void test8(){
    
    
        boolean result = personList.stream().anyMatch((person -> person.getName().equals("张三")));
        boolean result1 = personList.stream().allMatch(person -> person.getName().contains("张"));
        boolean result2 = personList.stream().noneMatch(person -> person.getName().contains("张"));
        System.out.println(result);
        System.out.println(result1);
        System.out.println(result2);
    }
    /**
     * 运行结果
     * true
     * false
     * false
     */

métodos de estadística

  • reducir((T, T) -> T) y reducir(T, (T, T) -> T)
@Test
    public void test9(){
    
    
        Integer max = personList.stream().map(Person::getAge).reduce(Integer::max).get();
        Integer min = personList.stream().map(Person::getAge).reduce(Integer::min).get();
        Integer sum = personList.stream().map(Person::getAge).reduce(0,Integer::sum);

        System.out.println(max);
        System.out.println(min);
        System.out.println(sum);
    }
    /**
     * 运行结果
     * 75
     * 14
     * 364
     */

Supongo que te gusta

Origin blog.csdn.net/lzfaq/article/details/122060851
Recomendado
Clasificación