java--ラムダ式

目次

ラムダ式の概要

ラムダ式エクササイズ

機能シリーズ

消費者シリーズ

述語シリーズ

サプライヤーシリーズ

メソッドリファレンス

コンストラクターリファレンス

アレイリファレンス


コードクラウドアドレス:https//gitee.com/bufanli/java8-demo.git

ラムダ式の概要

Lambdaは匿名の関数です。Lambda式は、渡すことができる(データのようにコードを渡す)コードの一部として理解できます。より簡潔で柔軟なコードを書くことができます。よりコンパクトなコードスタイルとして、Javaの言語表現能力が向上しました。

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(){
               
     }

   

}

ラムダ式エクササイズ

歌う

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

1. Collections.sort()メソッドを呼び出し、渡すパラメーターとしてラムダを使用して、カスタムソート(最初は年齢、同じ年齢、名前)で2人の従業員を比較します

 /**
      * 数据集合
      */
     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.名声のある機能インターフェイス。インターフェイスは、メソッドpublic String getValue(String str)を宣言して、文字列を大文字に変換し、メソッドの戻り値として使用します。

@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. 2つのジェネリックを使用して機能インターフェイスを宣言します。ジェネリックタイプは<T、R> TはパラメーターRは戻り値、2つのロングタイプパラメーターの合計が計算され、2つのロングタイプパラメータータイプの乗算が計算されます。

インターフェース

@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);
     }

機能シリーズ

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

関数は、パラメーターと戻り値を持つ関数を表します。多くの同様の関数インターフェースがあります:

インターフェイス名 説明
BiFunction<T,U,R> タイプTとタイプUの2つのパラメーターを受け取り、タイプRの結果を返す関数
DoubleFunction<R> ダブルタイプのパラメーターを受け取り、Rタイプの結果を返す関数
IntFunction<R> int型パラメーターを受け取り、R型の結果を返す関数
LongFunction<R> 長いタイプのパラメーターを受け取り、Rタイプの結果を返す関数
ToDoubleFunction<T> T型パラメータを受け取り、double型の結果を返します
ToIntFunction<T> Tタイプのパラメータを受け取り、intタイプの結果を返します
ToLongFunction<T> T型パラメータを受け取り、長い型の結果を返す
DoubleToIntFunction ダブルタイプパラメータを受け取り、intタイプの結果を返します
DoubleToLongFunction ダブルタイプパラメータを受け取り、ロングタイプの結果を返します

パラメータが結果を返さないことは明らかであるか、結果がパラメータタイプを認識していないことは明らかであるか、またはその両方です。

  /**
      * 函数型接口  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);
     }

消費者シリーズ

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

コンシューマーシリーズには、ファンクションシリーズと同様に、ここにリストされていないさまざまな派生インターフェイスがあります。ただし、これらはすべて同様の特性を持っています。つまり、結果は返されません。

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

述語シリーズ

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

Predicateシリーズのパラメーターは固定されていませんが、返されるタイプはブール値である必要があります。

 /**
      * 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;
     }

サプライヤーシリーズ

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

サプライヤーシリーズ、英語の翻訳は、名前が示すように「サプライヤー」です。出力のみで、料金はかかりません。したがって、パラメータを受け入れず、Tタイプの結果を返します。

 /**
      * 供给型对象产生一些对象
      */
     @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;
     }

メソッドリファレンス

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());

     }
}

 コンストラクターリファレンス

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();
     }
}

アレイリファレンス

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);
     }
}

 

おすすめ

転載: blog.csdn.net/adminBfl/article/details/88354717