zoukankan      html  css  js  c++  java
  • Java8实战系列一

    从java7到java8,最主要的变化可以总结为

    Lambda表达式

    方法引用

    □流和默认方法

    让我们通过一个小例子感受一下

    情景 1 集合对象排序 (对list中的苹果按照重量排序)

    1. Collections.sort(list,new Comparator<Apple>(){
    2.    public int compare(Apple a1,Apple a2){
    3.       return a1.getWeight()-a2.getWeight();
    4.    }
    5. });

    在java8里面,这种实现只需要一行很简短的代码

    1. list.sort(java.util.Comparator.comparing(Apple::getWeight))

    这其中涉及到lambda表达式,接口中静态方法,方法引用等java8新特性,而且一看就明白其功能,给list排序,排序依据weight

    Java多线程历程 java1.0 线程和锁------à java5 线程池和并发集合----------à java7 添加分支/合并(fork/join)--à java8 添加stream支持并发处理数据

    在java8中加入Streams可以把 接口默认方法和把代码块传递给方法的简介方式(方法引用、lambda表达式)

    把代码传递给方法 即是一种行为参数化思想,和函数式编程思想极为相近。

    情景2 对目录文件过滤,筛选所有隐藏文件

    1. File [] hiddenFiles=new File(".").listFiles(new FileFilter(){
    2.    public boolean accept(File file){
    3.       return file.isHidden();
    4.    }
    5. });

    使用方法引用,直接将方法当做参数传递进去

    1. File [] hiddenFiles=new File(".").listFiles(File::isHidden)

    既然对象File已经有了一个isHidden方法,我们不必再把它包含在啰嗦的匿名内部类里面过滤了。

    与用对象引用(对象引用是用new创建的)类似,写下File::isHidden就创建一个方法引用,可以传递它

    如可以写成这样

    1. FileFilter filter=File::isHidden;
    2. File [] isHiddenFiles2=new File(".").listFiles(filter);

    从第一行代码可以看出,方法引用确实可以当做一个变量来使用

     

    情景3 lambda传递条件代码 (筛选符合条件的苹果)

    1. public static List<Apple> filterGreenApple(List<Apple> list){
    2.  
    3.    List<Apple> result=new ArrayLst<>();
    4.    for(Apple apple : list){
    5.       if("green".equals(apple.getColor())){
    6.          result.add(apple); //筛选颜色为绿色的苹果
    7.       }
    8.    }
    9.    return result;
    10. }
    11. public static List<Apple> filterWeighterApple(List<Apple> list){
    12.  
    13.    List<Apple> result=new ArrayLst<>();
    14.    for(Apple apple : list){
    15.       if(apple.getWeight()>150){
    16.          result.add(apple); //筛选重量大于150g的苹果
    17.       }
    18.    }
    19.    return result;
    20. }

    如果客户要筛选红苹果,筛选红且重量大于150g的苹果,…难道每次都要添加一个函数吗,而且这些函数除了条件筛选不一样,其他部分都是一样的。

    首先我们可以把公用代码提出来

    1. public static List<Apple> filterApple(List<Apple> list){
    2.    List<Apple> result=new ArrayList<>();
    3.    for(Apple apple:list){
    4.       if(....){ //苹果筛选条件
    5.          result.add(apple);
    6.       }
    7.    }
    8.    return result;
    9. }
    10. 进一步,我们可以把筛选条件传递进去 过滤函数可以改成这样
    11. public static List<Apple> filterApple(List<Apple> list,Predicate<Apple> p){
    12.    List<Apple> result=new ArrayList<>();
    13.    for(Apple apple:list){
    14.       if(p.test(apple)){
    15.          result.add(apple);
    16.       }
    17.    }
    18.    return result;
    19. }
    20. Public interface Predicate<Apple>{
    21.     Boolean test(Apple apple);
    22. }

    即过滤函数有两个参数,一个时过滤的对象集合,一个时过滤的 条件对象(Predicate),而该条件对象应该有个可以返回Boolean的函数来确定是否符合条件(策略设计模式)

    这样设计之后,把filterApple方法迭代集合的逻辑和要应用到集合中每个元素对象上的行为(谓词)区分开了。

    比如要筛选出绿苹果

    1. public class GreenColorPredicate<Apple> implements Predicate<Apple>{
    2.    public boolean test(Apple apple){
    3.       if("green".equals(apple.getColor())){
    4.          return true;
    5.       }
    6.       return false;
    7.    }
    8. }
    9. GreenColorPredicate<Apple> greenPredicate=new GreenColorPredicate<>();
    10. filterApple(list,greenPredicate);

     

    或者lambda表达式

    1. filterApple(list,(Apple apple)->"green".equals(apple.getColor()));

    我们可以将上面的函数抽象化成泛型函数,这样就可以过滤香蕉,橘子等对象集合啦!!

    行为参数化最大好处就是可以适应不断变化的需求。

     

    总结:

    1 行为参数化,就是一个方法接受多个不同的行为作为参数,在内部使用它们,完成不同行为的能力。

    2 行为参数化可以让代码更好适应不同需求,减轻未来工作量。

    3 传递代码,即将新行为作为参数传递给方法。可以用lambda表达式或者方法引用。

    4 java api包含很多可以用不同行为进行参数化的方法,最常用就是排序,线程等。

     

     

  • 相关阅读:
    学期总结
    Sprint 2(第一天)
    学期总结
    实验四、主存空间的分配和回收
    阅读《构建之法》与链接有感.
    《构建之法》八、九、十章读后感
    Scrum领取任务
    实验三、进程调度模拟程序实验
    《构建之法》6-7章读后感
    实验二 作业调度模拟程序
  • 原文地址:https://www.cnblogs.com/gaochaochao/p/9991518.html
Copyright © 2011-2022 走看看