目录

Lambda表达式

目录

一、语法

  1. 表达式-风格

    (parameters) -> expression
    
  2. 块-风格

    • 特殊的是:返回值为void的单行方法调用不需要用括号环绕。
    (parameters) -> { statements; }
    

二、使用

Lambda 表达式的使用需要借助于函数式接口,也就是说只有函数式接口出现地方,我们才可以将其用 lambda 表达式进行简化。
函数式接口定义:仅含有一个抽象方法的接口。

  1. 例子
  • 函数式接口
    @FunctionalInterface
    public interface Comparator<T> {
        int compare(T o1, T o2);
    }
    
  • 使用示例
    Comparator<Apple> appleComparator =(Apple a1, Apple a2) -> a1.getWeight - a2.getWeight;
    
    appleComparator.compare(new Apple(200), new Apple(210));
    
  1. 例子
  • 函数式接口
    @FunctionalInterface
    public interface Runnable {
        public abstract void run();
    }
    
  • 使用示例
    // 不使用Lambda表达式:
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Before Java8, too much code for too little to do");
        }
    }).start();
    
    //使用Lambda表达式:
    new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();
    

三、常用函数式接口

  • 函数式接口可以对现有的函数友好地支持 lambda,在JDK中已有一些函数式接口。
  1. Predicate

    • 适用场景:表示一个涉及类型T的布尔表达式。

    • 接口源代码

      public interface Predicate<T> {
          boolean test(T t);
      }
      
    • 使用示例

      public static void main(args[]){
          List fruits = Arrays.asList("西瓜", "哈密瓜", "杨梅", "苹果", "榴莲");
      
          filter(languages, (str)->str.endsWith("瓜"));
      }
      
      public static void filter(List fruits, Predicate condition) {
          for(String fruit: fruits)  {
              if(condition.test(fruit)) {
                  System.out.println(fruit + " ");
              }
          }
      }
      
  2. Consumer

    • 适用场景:访问类型T的对象,对其执行某些操作。

    • 接口源代码

      public interface Consumer<T> {
          void accept(T t);
      }
      
    • 使用示例

      Consumer<People> peopleConsumer = p -> System.out.println("我的名字叫" + p.getName());
      appleWeighter.accept(new People("张三"));
      
  3. Function

    • 适用场景:将输入对象转换输出。

    • 接口源代码

      public interface Function<T, R> {
          R apply(T t);
      }
      
    • 使用示例

      Function<People, String> AgeOfPeople = p -> p.getName() + "的年龄是" + p.getAge();
      NameOfPeople.apply(new People("张三",12));
      

四、方法引用

  1. 静态方法的方法引用

    • 不使用方法引用
      Function<String, Integer> fun = s -> Integer.parseInt(s);
      
    • 使用方法引用
      Function<String, Integer> fun = Integer::parseInt;
      
  2. 实例方法的方法引用

    • 不使用方法引用
      Function<String, Integer> fun = s -> s.length();
      
    • 使用方法引用
      Function<String, Integer> fun = String::length;
      
  3. 现存外部对象实例方法的方法引用

    • 不使用方法引用
      String s = "方法引用";
      Supplier<Integer> len = () -> s.length();
      
    • 使用方法引用
      String s = "方法引用";
      Supplier<Integer> len = s::length;
      

五、在流处理中使用Lambda表达式

  1. forEach、limit、sorted

    //使用 forEach 输出10个排序后的随机数
    Random random = new Random();
    random.ints().limit(10).sorted().forEach(System.out::println);
    
  2. map、collect

    // 获取对应的平方数,结果转为集合
    List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
    List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
    
  3. filter、count

    //获取空字符串的数量
    List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
    long count = strings.stream().filter(string -> string.isEmpty()).count();
    
  4. Collectors

List<String>strings = Arrays.asList("aaa", "", "bbb", "ccc", "","ddd");
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
  1. 统计结果的收集器(主要用于int、double、long等基本类型上)
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
 
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
 
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
← 返回技术