Java8实战阅读笔记(Lambda表达式)

3.1 Lambda 管中窥豹

可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表利用Lambda表达式,可以更为简洁地自定义一个Comparator对象。
在这里插入图片描述

// 先前
 Comparator<Apple> byWeight = new Comparator<Apple>() {
        public int compare(Apple a1, Apple a2){
            return a1.getWeight().compareTo(a2.getWeight());
        }
    };
 // 之后
 Comparator<Apple> byWeight =
            (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

参数列表——这里它采用了Comparator中compare方法的参数,两个Apple。
箭头——箭头->把参数列表与Lambda主体分隔开。
Lambda主体——比较两个Apple的重量。表达式就是Lambda的返回值了。
在这里插入图片描述

3.2 在哪里以及如何使用 Lambda

可以在上一章中实现的filter方法中使用Lambda可 以 把 Lambda 表 达 式 作 为 第 二 个 参 数 传 给 filter 方 法因 为 它 这 里 需 要Predicate,而这是一个函数式接口

List<Apple> greenApples =filter(inventory, (Apple a) -> "green".equals(a.getColor()))
3.2.1 函数式接口

它就是一个函数式接口!因为Predicate仅仅定义了一个抽象方法 函数式接口就是只定义一个抽象方法的接口

public interface Predicate<T>{
	boolean test (T t);
}

3.3 使用函数式接口

3.3.1 Predicate

接口定义了一个名叫test的抽象方法,它接受泛型T对象,并返回一个boolean。

      public interface Predicate<T>{
            boolean test(T t);
        }

 public  static <T> List<T> filter (List<T>  list, Predicate<T> p){
        List<T> results = new ArrayList<>();
        for (T s : list){
            if(p.test(s)){
                results.add(s);
            }
        }
        return results;
    }

List<Apple> appleList = new ArrayList<>();
// 筛选重量等于1得苹果
filter(appleList,(Apple a)->a.getWeight() == 1 );
// 筛选红色得苹果
filter(appleList,(One.Apple a)->a.getColor().equals("red"));
3.3.2 Consumer

定义了一个名叫accept的抽象方法它接受泛型T的对象,没有返回( void)。你如果需要访问类型T的对象,并对其执行某些操作,就可以使用这个接口

   public  static <T> void filter (List<T>  list, Consumer<T> p){
        for (T i : list){
            p.accept(i);
        }
    }
    
 filter(appleList,(Apple i)-> System.out.println(i));
3.3.3 Function

定义了一个叫作apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象

    public static <T,R> List<R>  map (List<T> list, Function<T,R> f){
        List<R> result  = new ArrayList<>();
        for (T s : list){
            result.add(f.apply(s));
        }
        return result;
    }
  
  List<Integer> map = map(Arrays.asList("1", "2"), (String s) -> s.length());
3.3.4 原始类型特化

在Java里有一个将原始类型转换为对应的引用类型的机制。这个机制叫作装箱( boxing)。相反的操作,也就是将引用类型转换为对应的原始类型,叫作拆箱( unboxing)。 但这在性能方面是要付出代价的。装箱后的值本质上就是把原始类型包裹起来,并保存在堆里。因此,装箱后的值需要更多的内存,并需要额外的内存搜索来获取被包裹的原始值
Java 8为我们前面所说的函数式接口带来了一个专门的版本,以便在输入和输出都是原始类
型时避免自动装箱的操作。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4 Lambda 和方法引用实战

用不同的排序策略给一个Apple列表排序

3.4.1 传递代码

Java 8的API已经为你提供了一个List可用的sort方法sort方法的签名是这样的

void sort(Comparator<? super E> c)

第一个解决方案

  List<Apple> appleList = new ArrayList<>();
  public class AppleComparator implements Comparator<Apple>{
        public int compare(Apple a1, Apple a2){
            return a1.getWeight().compareTo(a2.getWeight());
        }
    }

appleList .sort(new AppleComparator());
3.4.2 使用匿名内部类
   appleList.sort(new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return o1.getWeight().compareTo(o2.getWeight());
            }
        });
3.4.3 使用lambda表达式
 appleList.sort((One.Apple o1, One.Apple o2)->o1.getWeight().compareTo(o2.getWeight()));

Java编译器可以根据Lambda出现的上下文来推断Lambda表达式参数的类型。那么你的解决方案就可以重写成这样:

 appleList.sort((o1,o2)->o1.getWeight().compareTo(o2.getWeight()));
3.4.4 使用方法引用
		import static java.util.Comparator.comparing;
        appleList.sort(comparing(Apple::getWeight));

3.5 复合Lambda表达式

3.5.1 比较复合器
逆序
   appleList.sort(comparing(Apple::getWeight).reversed());
比较链

如果发现有两个苹果一样重怎么办?哪个苹果应该排在前面呢?比如,在按重量比较两个苹果之后,你可能想要按颜色排序

  appleList.sort(comparing(Apple::getWeight)
                    .reversed()
                    .thenComparing(Apple::getColor));

3.5.2 谓词复合

谓词接口包括三个方法: negate、 and和or,让你可以重用已有的Predicate来创建更复
杂的谓词

产生现有Predicate对象redApple的非

  public static class ColorPredicate implements Predicate<Apple> {
        @Override
        public boolean test(Apple apple) {
            return false;
        }
    }
    
  ColorPredicate colorPredicate = new ColorPredicate();
  Predicate<Apple> negate = colorPredicate.negate();

链接两个谓词来生成另一个Predicate对象

     Predicate<Apple> and = negate.and(a -> a.getWeight() > 150);

链接Predicate的方法来构造更复杂Predicate对象

      Predicate<Apple> and = negate
                .and(a -> a.getWeight() > 150)
                .or(a->a.getColor().equals("green"));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值