java8新特性

lambda表达式:https://www.cnblogs.com/haixiang/p/11029639.html

lambda表达式

lambda表达式是一个匿名函数,可以理解为一段可传递的代码。

 public void test() {
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };
    }
 public void test1() {
     Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);
 }

需求:过滤年龄大于30的学生,成绩大于90的学生
传统写法,for循环遍历比较返回。
优化一:策略者模式
1、定义比较接口

public interface Compare<T> {
    boolean com(T t);
}

2、书写实现类

public class FilterByAge implements Compare<Student> {
    @Override
    public boolean com(Student student) {
        return student.getAge() >= 22;
    }
}

3、调用

filterStu(students,new FilterByAge());
# 成绩的筛选同样的实现方式书写即可

优化2:匿名内部类
省去接口实现的步骤直接使用匿名内部类

filterStu(students, new Compare<Student>() {
         @Override
         public boolean com(Student student) {
             return student.getAge() > 22;
         }
     });

优化3:lambda表达式

List<Student> list = filterStu(students,(e) -> e.getAge() > 56);
      // 打印输出
      list.forEach((e)-> System.out.println(e.getAge()));
      // 打印输出
      list.forEach(System.out::println);

优化方式四:Stream API
直接基于原始数据去遍历,一句代码搞定

 students.stream().filter((e) -> e.getAge() >22).forEach(System.out::println);

基础语法

  • -> 操作符
    将表达式lamda表达式拆分为两个部分,左侧为参数,右侧为操作执行
    左侧对应抽象方法 右侧对应实现
  • 无参函数
 @Test
public void testL() {
      Runnable r = new Runnable() {
          @Override
          public void run() {
              System.out.println("lamda!");
          }
      };
      // 等价于,通过lamda表达式实现无参run方法
      Runnable lamdaR = () -> System.out.println("lamda!");
  }

注意:同匿名内部类一样使用同的变量只可读,不可写,因为变量会自动加上final,这是规定。
如下匿名内部类和lamda表达式都不能修改num的值

 @Test
public void testL() {
	 int num;
      Runnable r = new Runnable() {
          @Override
          public void run() {
              System.out.println("lamda!");
          }
      };
      // 等价于,通过lamda表达式实现无参run方法
      Runnable lamdaR = () -> System.out.println("lamda!");
  }
  • 只有一个参数,()可以不写
List<Student> list = filterStu(students,(e) -> e.getAge() > 56);
List<Student> list = filterStu(students,e -> e.getAge() > 56);
  • 两个参数、多条语句,并且有返回值
    多条语句需要加大括号{}
Comparator<Integer> comparator = (x,y) -> {
          System.out.println(x);
          System.out.println(y);
          return Integer.compare(x,y);
      };
  • 两个参数,一条语句,有返回值return和{}都可以不写
  • lamda的表达式的参数列表可以省略不写,可以JVM可以通过上下文进行推断,也可以写上。

函数式接口

通过上面的例子可以发现,lamda表达式依赖于函数式接口,里面只能有一个抽象方法。

public interface Calculate {
    int op(int a,int b);
}

@Test
    public void testL() {
     System.out.println(op(10,10,(a,b) -> a + b));
     System.out.println(op(10,10,(a,b) -> a * b));
     System.out.println(op(10,10,(a,b) -> a - b));
     System.out.println(op(10,10,(a,b) -> a / b));
    }
   public int op (int a,int b ,Calculate calculate) {
        return calculate.op(a,b);
   }

接口申明方法,具体实现由lamda完成

Java四大内置函数式接口

  • consumer:消费型接口
    void accept(T t);
@Test
    public void testL() {
        int money = 100;
         op(money,a -> a -= 10);
         op(money,b -> b -= 100);
    }
   public void op (int a, Consumer<Integer> consumer) {
         consumer.accept(a);
   }
  • Supplier :提供型接口
    T get();
   @Test
    public void testL() {
        List<Integer> list = new ArrayList<>();
        // 获取随机数并加入集合
        list.add(op(() -> (int)Math.random()));
    }
   public int op (Supplier<Integer> supplier) {
         return supplier.get();
   }
  • Function<T,R> : 函数型接口
    R apply(T t);
 @Test
    public void testL() {
        op("liyong",(str) -> str.trim());
        op("liyong",(str) -> str.toUpperCase());
    }
   public String op (String str,Function<String,String> function) {
         return function.apply(str);
   }
  • Predicate :断言接口
    Boolean test(T t);
@Test
   public void testL() {
       op("liyong",(str) -> str.equals("liyong"));
   }
  public boolean op (String str, Predicate<String> predicate) {
        return predicate.test(str);
  }
  • 其他接口
    在这里插入图片描述

方法引用

  • 对象::实例方法名
    方法已经被实现且返回值类型,参数列表与函数式接口的抽象方法保持一致
Student student = new Student(23,"liyong",888888888);
Supplier<Integer> supplier = () -> student.getAge();
 // 等价于
 Supplier<Integer> supplier = () -> student::getAge;
  • 类::静态方法名
 Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);
 // 等价于
 Comparator<Integer> comparator = Integer::compare;
  • 类::实例方法名
// 使用规则,第一个参数是实例方法的调用者,第二个参数为实例方法的参数
BiPredicate<String,String> biPredicate = (x,y) -> x.equals(y);
BiPredicate<String,String> biPredicate = String::equals;

构造器引用

ClassName::new
由于Suppliers为无参,则调用无参构造

Supplier<Student> supplier =Student::new;
Student student = supplier.get();

数组引用

Function<Integer,String[]> function = String[]::new;
String[] strings = function.apply(10);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值