java--lambda expression

table of Contents

Overview of lambda expressions

Lambda expression exercise

Function series

Consumer series

Predicate series

Supplier series

Method reference

Constructor reference

Array reference


Code cloud address: https://gitee.com/bufanli/java8-demo.git

Overview of lambda expressions

Lambda is an anonymous function. We can understand Lambda expression as a piece of code that can be passed (passing the code like data). You can write more concise and flexible code. As a more compact code style, the language expression ability of Java has been improved.

package cn.bufanli.lambda;

import cn.bufanli.pojo.Employee;
import cn.bufanli.service.MyEmployeesService;
import cn.bufanli.service.impl.MyEmployeesAgeServiceImpl;
import cn.bufanli.service.impl.MyEmployeesSalaryServiceImpl;
import org.junit.Test;

import java.beans.Visibility;
import java.util.*;
import java.util.function.Consumer;

/**
 *   一.lambda表达式需要函数式接口的支持
 *        函数式接口: 接口中只有一个方法的接口为函数式接口
 *        使用 @FunctionalInterface  注解可以检查接口是否是函数是借口 和@Service 注解使用一样
 *   二.lambda表达式的基础语法
 *   java8引入了一个新的操作符号 "->" 该操作符是箭头操作符或者lambda操作符
 *        箭头操作符将lambda表达式拆分成左右两部分
 *        左: lambda表达式的参数列表
 *        右: lambda表达式所需执行的功能,lambda体
 *   语法格式一:
 *        接口中的方法:无参数、无返回值
 *             函数式接口名 变量名 = () -> System.out.println("Hello Lambda");
 *   语法格式二:
 *        接口中的方法:有一个参数、无返回值
 *             函数式接口名 变量名 =(x) -> System.out.println(x);
 *   语法格式三:
 *        接口中的方法:如果只有一个参数小括号可以省略不写、无返回值
 *             函数式接口名 变量名 = x -> System.out.println(x);
 *   语法格式四:
 *        接口中的方法:有多个参数、有返回值 、多条语句
 *             Comparator<Integer> comparator=(x,y)->{
 *                  System.out.println("函数式接口");
 *                  return Integer.compare(x,y);
 *             };
 *   语法格式五:
 *        接口中的方法:有多个参数、有返回值 、只有条语句大括号可以省略、return 可以省略
 *             Comparator<Integer> comparator=(x,y)->Integer.compare(x,y);
 *   语法格式六:
 *        参数列表的数据类型可以省略不写,java JVM编译器可通过上下文推断出数据类型
 */
public class Testlambda2 {

     /**
      * 语法格式一:参数、无返回值
      */
     @Test
     public void test01(){
          //jdk1.7 必须加 final 修饰
          int num=0;

          Runnable hello_lambda = new Runnable() {
               @Override
               public void run() {
                    System.out.println("hello Lambda"+num);
               }
          };
          hello_lambda.run();
          System.out.println("--------------------------");
          Runnable hello_lambda2= () -> System.out.println("Hello Lambda");
          hello_lambda2.run();
     }
     /**
      * 语法格式二:有一个参数、无返回值
      */
     @Test
     public void test02(){
          Consumer com =(x) -> System.out.println(x);
          com.accept("666");
     }
     /**
      * 语法格式三:只有一个参数小括号可以省略不写、无返回值
      */
     @Test
     public void test03(){
          Consumer com =x -> System.out.println(x);
          com.accept("666");
     }

     /**
      * 语法格式四:有多个参数、有返回值 多条语句
      */
     @Test
     public void test04(){
         Comparator<Integer> comparator=(x,y)->{
              System.out.println("函数式接口");
              return Integer.compare(x,y);
         };

     }
     /**
      * 语法格式五:有多个参数、有返回值 、只有条语句大括号可以省略、return 可以省略
      */
     @Test
     public void test05(){
         Comparator<Integer> comparator=(x,y)->Integer.compare(x,y);
     }
     /**
      * 语法格式六 参数类型可以通过上下文自动推断
      */
     @Test
     public void test06(){
          // <Integer> 没有他就会报错
          Comparator<Integer>  comparator=( x, y)->Integer.compare(x,y);

          String [] strs={"aaa","bbb" };
          String [] strs2;
          //会报错strs2={"aaa","bbb" };
          //<Object> 没有他会报错
          ArrayList<Object> objects = new ArrayList<>();
          //jdk 1.8 不需要写他根据目标方法的类型可以推断
          show(new HashMap<>());
     }
     public void show(Map<String,Integer> map){}

     @Test
     public void test07(){
               
     }

   

}

Lambda expression exercise

sing

public class Employee {
     // 名字
     private String name;
     // 年龄
      private Integer age;
     //薪资
     private double salary;
略 get and set  空参 有参构造 toString
}

1. Call the Collections.sort() method, compare two Employee by custom sorting (first by age, the same age, by name), use lambda as the parameter to pass

 /**
      * 数据集合
      */
     List<Employee> employees = Arrays.asList(
              new Employee("张三",36,8899.99),
              new Employee("李四",25,4499.99),
              new Employee("王五",15,5599.99),
              new Employee("赵六",35,3399.99),
              new Employee("天气",5,2299.99)
     );
     @Test
     public void test1(){
          Collections.sort(employees,(e1,e2)->{
               if(e1.getAge().equals(e2.getAge())){
                    return e1.getName().compareTo(e2.getName());
               }else{
                    return Integer.compare(e1.getAge(),e2.getAge());

               }
          });
          employees.forEach(employee -> System.out.println(employee));
     }

  2. Fame functional interface, the interface declares the method public String getValue(String str) to convert a string to uppercase and use it as the method return value

@FunctionalInterface
public interface GetStringValue {
     String getStringValue(String str);
}

 

     @Test
     public void test2(){
          System.out.println(getValue("aaa", (str) -> str.toUpperCase()));
     }
     public String getValue(String str, GetStringValue getStringValue){
          return getStringValue.getStringValue(str);
     }

3. Declare a functional interface with two generics, the generic type is <T, R> T is the parameter R is the return value, the sum of the two Long-type parameters is calculated, and the multiplication of the two Long-type parameter types is calculated

interface

@FunctionalInterface
public interface LambdaSumDemo<T,R> {
     R sum(T t,R r);
}
 @Test
     public void test3(){
          System.out.println(operation(3L, 4L, (l1, l2) -> l1 + l2));
          System.out.println(operation(3L, 4L, (l1, l2) -> l1 * l2));
     }
     /**
      * 对于两个Long类型数据处理
      * @param l1
      * @param l2
      * @param lambdaSumDemo
      */
     public Long operation(Long l1, Long l2, LambdaSumDemo<Long,Long> lambdaSumDemo){
        return lambdaSumDemo.sum(l1, l2);
     }

Function series

@FunctionalInterface
public interface Function<T, R> {
	// 接收一个参数T,返回一个结果R
    R apply(T t);
}

Function represents a function with parameters and a return value. There are many similar Function interfaces:

Interface name description
BiFunction<T,U,R> A function that receives two parameters of type T and U and returns a result of type R
DoubleFunction<R> A function that receives a double type parameter and returns an R type result
IntFunction<R> A function that receives an int type parameter and returns an R type result
LongFunction<R> A function that receives long type parameters and returns R type results
ToDoubleFunction<T> Receive T type parameter and return double type result
ToIntFunction<T> Receive T type parameter and return int type result
ToLongFunction<T> Receive T type parameter and return long type result
DoubleToIntFunction Receive double type parameter, return int type result
DoubleToLongFunction Receive double type parameter, return long type result

Either it is clear that the parameter does not return the result, or it is clear that the result does not know the parameter type, or both.

  /**
      * 函数型接口  Function<T,R>
      */
     @Test
     public void test04() {
          String asdada = getStr("asdada", (x) -> {
               return x.toUpperCase();
          });
          System.out.println("大写:"+asdada);
          //只有一个参数,方法体内只有一条语句 小括号 return 大括号可以省略
          String asdada2 = getStr(asdada, x -> x.toLowerCase());
          System.out.println("小写:"+asdada2);
     }
     /**
      * 用于处理字符串
      */
     public String getStr(String s, Function<String, String> function) {
          return function.apply(s);
     }

Consumer series

@FunctionalInterface
public interface Consumer<T> {
	// 接收T类型参数,不返回结果
    void accept(T t);
}

The Consumer series, like the Function series, has various derivative interfaces, which are not listed here. But they all have similar characteristics: that is, no results are returned.

    /**
      * Consumer 消费型接口
      */
     @Test
     public void test01(){
          happy(1000.0,(x)->{
               System.out.println("工资:" + x + "元");
          });
     }
     public  void happy(double money, Consumer<Double> con){
          con.accept(money);
     }

Predicate series

@FunctionalInterface
public interface Predicate<T> {
	// 接收T类型参数,返回boolean类型结果
    boolean test(T t);
}

The parameters of the Predicate series are not fixed, but the returned type must be boolean.

 /**
      * Predicate 断言
      */
     @Test
     public void test05(){
          List<String> strings = Arrays.asList("百度", "腾讯->过滤", "阿里", "京东->过滤");
          List<String> strings1 = filterStr(strings, x -> x.length() > 3);
          System.out.println(strings1);
     }
     /**
      * 将满足条件的字符串,放入集合中
      * @param list 传入需要过滤的字符串集合
      * @param stringPredicate
      * @return
      */
     public List<String> filterStr(List<String> list, Predicate<String> stringPredicate){
          ArrayList<String> strings = new ArrayList<>();
          for (String string : list) {
               if(stringPredicate.test(string)){
                    strings.add(string);
               }
          }
          return strings;
     }

Supplier series

@FunctionalInterface
public interface Supplier<T> {
	// 无需参数,返回一个T类型结果
    T get();
}

Supplier series, the English translation is "supplier", as the name implies: only output, not charge. Therefore, it does not accept any parameters and returns a T type result.

 /**
      * 供给型对象产生一些对象
      */
     @Test
     public void test02(){
          List<Integer> numList = getNumList(3, () -> (int) (Math.random() * 100));
          System.out.println(numList);
     }

     /**
      * 产生制定个数的整数一些数放入集合中
      * @param num 数组的长度
      * @param supplier 供给型接口
      * @return
      */
     public List<Integer> getNumList(int num, Supplier<Integer> supplier) {
          List<Integer> objects = new ArrayList<>();
          for (int i=0;i<num;i++){
               // 生成的随机数
               Integer integer = supplier.get();
               objects.add(integer);
          }
          return objects;
     }

Method reference

package cn.bufanli.lambda;

import cn.bufanli.pojo.Employee;
import org.junit.Test;

import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * @author BuShuangLi
 * @date 2019/3/11
 * 方法引用: 若lambda 体中的内容有方法已经实现了,我们可以使用"方法引用"
 *   (可以理解为方法引用是lambda 表达式的另一种表现形式)
 *  主要有三种语法格式:
 *
 *   对象::实例方法名
 *
 *   类::静态方法名
 *
 *   类::实例方法名(非静态方法)
 * 注意:
 *   ①: lambda体中的参数列表和返回值与引用的函数式接口方法参数列表和返回值一致
 *   ②: 第一个参数是实例方法的调用者,第二个参数这是实例方法的参数时可以使用 类::实例方法名
 */
public class Testlambda5 {
     /**
      * 类::实例方法名
      */
     @Test
     public void test03(){
          BiPredicate<String,String> biPredicate =(x,y)->x.equals(y);
          //第一个参数是实例方法的调用者,第二个参数这是实例方法的参数时
          BiPredicate<String,String> biPredicate2 =String::equals;

     }

     /**
      * 类::静态方法名
      */
     @Test
     public void test02(){
          Comparator<Integer> com=(x,y)->Integer.compare(x,y);
          Comparator<Integer> com2=Integer::compare;

     }
     /**
      * 对象::实例方法名
      */
     @Test
     public void test01(){
          //1
          Consumer<String> con = x -> System.out.println(x);

          //可以用方法引用  lambda体中的参数列表和返回值与引用的方法返回值和参数列表一致
          PrintStream ps =System.out;
          //2
          Consumer<String> s= ps::println;
          //3
          Consumer<String> s2= System.out::println;
          s2.accept("阿达");

          Employee employee = new Employee();
          employee.setName("测试");
          Supplier<String> sp=employee::getName;
          System.out.println(sp.get());

     }
}

 Constructor reference

package cn.bufanli.lambda;

import cn.bufanli.pojo.Employee;
import org.junit.Test;

import java.util.function.Supplier;

/**
 * @author BuShuangLi
 * @date 2019/3/11
 * 构造器引用
 *   格式:
 *   ClassName::new
 *   需要调用的构造器的参数列表要与函数式接口中抽象的方法参数列表保持一致
 */
public class Testlambda6 {

     @Test
     public void test01(){
          Supplier<Employee> supplier=()->new Employee();
          Employee employee = supplier.get();
          //构造器引用
          Supplier<Employee> supplier2=Employee::new;
          Employee employee1 = supplier2.get();
     }
}

Array reference

package cn.bufanli.lambda;

import org.junit.Test;

import java.util.function.Function;

/**
 * @author BuShuangLi
 * @date 2019/3/11
 * 数组引用
 * Type[]::new;
 *
 */
public class Testlambda7 {
     @Test
     public void test01(){
          Function<Integer,String[]> fun=x -> new String[x];
          String[] apply = fun.apply(10);
          System.out.println(apply.length);
          Function<Integer,Integer[]> fun2=Integer[]::new;
          Integer[] apply1 = fun2.apply(10);
          System.out.println(apply1.length);
     }
}

 

Guess you like

Origin blog.csdn.net/adminBfl/article/details/88354717