Java8 in action

一、为何关注Java8

Java8提供了更多的编程工具和概念,能以更快、更为简洁、更易于维护的方式解决新的或者现有的编
程问题;

流处理:
尽管流水线实际是一个序列,但不同的加工站的运行一般是并行的。

用行为参数化把代码传递给方法。

Java演进

泛型 for each循环
Java8引入的新思想:侧重改变现有值的经典面向对象思想------>>>函数式编程领域转变

Java中的函数和新的Stream API

Java中的函数

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

});

java8里,可以用::把isHidden函数传递给listFiles方法

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

```java 


Lambda匿名函数  (允许匿名函数为一等值)


```java 
//给定参数x,返回x+1
(int x) -> x + 1

函数式编程《========》编写把函数作为一等值来传递的程序

传递代码

//筛选绿色的苹果
public static List<Apple> filterGreenApples(List<Apple> inventory ){
   List<Apple> result = new ArrayList<>();
   for(Apple apple : inventory){
      if("green".equals(apple.getColor())){
         result.add(apple);
      }
   }
   return result;
}

//仅仅选出重的苹果
public static List<Apple> filterGreenApples(List<Apple> inventory ){
   List<Apple> result = new ArrayList<>();
   for(Apple apple : inventory){
      if(apple.getWeight() > 150){
         result.add(apple);
      }
   }
   return result;
}
public static boolean isGreenApple(Apple apple){
   return "green".equals(apple.getColor());
}

public static boolean isHeavyApple(Apple apple){
    return apple.getWeight() > 150;
}

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

//方法作为谓词传递进去
static List<Apple> filterApples(List<Apple> inventory,Predicate<Apple> p){
   List<Apple> result = new ArrayList<>();
   for(Apple apple : inventory){
      if(p.test(apple)){
         result.add(apple);
      }
   }
   return result;
}

//filterApples的用法
filterApples(inventiory,Apple::isGreenApple);

filterApples(inventiory,Apple::isGreenApple);

Predicate(谓词)

前面的代码传递了方法Apple::inGreenApple (它接受参数Apple并返回一个boolean)给filterApples,
后者希望接受一个Predicate<Apple>参数值,谓词在数学上用来形容类似函数的东西

从传递方法到Lambda
把方法作为值来传递显然很有用,但是为isGreenApple和isGreenApple这种短方法写一堆定义有点麻
烦。所以引入了匿名表达式或lambda

filterApples(inventory, (Apple a) -> "green".equals(a.getColor()));

filterApples(inventory, (Apple a) -> a.getWeight() > 150);

filterApples(inventory, (Apple a) ->  a.getWeight() < 80 ||
"brown".equals(a.getColor()));
static <T> Collection<T> filter(Collection<T> c , Predicate<T> p);
filterApples(inventory,(Apple a) -> a.getWeight() > 150);
filter(inventory,(Apple a) -> a.getWeight() > 150);

Map<Currency,List<Transaction>> transactionsByCurrencies = new HashMap<>();
for(Transaction transaction : transactions){
   if(transaction.getPrice() > 1000){
      Currency currency = transaction.getCurrency();
      List<Transaction> transactionsForCurrency =
transactionsForCurrencies.get(currency);
      if(transactionsForCurrency == null){
         transactionsForCurrency = new ArrayList<>();
         transactionsForCurrencies.put(currency , transactionsForCurrency);
      }
      transactionsForCurrency.add(transaction);
   }

}

等价的筛选代码

import static java.util.stream.Collection.toList;
Map<Currency,List<Transaction>> transactionsForCurrencies = transaction.stream().filter(
(Transaction t) -> t.getPrice() > 1000).collect(groupingBy(Transaction :: getCurrency));

并行处理

import static java.util.stream.Collection.toList;
List<Apple> heavyApples = inventory.parallelStream().filter((Apple a) -> a.getWeight()
>150 ).collect(toList());

默认方法:

List<Apple> heavyApple1 = inventory.stream().filter( (Apple a) -> a.getWeight() > 150 ).collect(toList());

List<Apple> heavyApple1 = inventory.parallelStream().filter( (Apple a) -> a.getWeight() > 150 ).collect(toList());

很多替代的集合类都实现了CollectionAPI接口,如果在Collection中加入一个新方法,意味着所有的实体类都必须为其提供一个实现

如何改变已发布的接口而不破坏已有的实现呢?

Java8中 接口如今可以包含实现类没有提供实现的方法签名,缺失的方法主体随接口提供了默认实现,而不是由实现类提供

第二章 通过行为参数化传递代码
应对不断变化的需求
行为参数化
匿名类
lambda表达式预览
真实示例:Comparator、Runnable和GUI

2.1 不断变化的需求
2.1.1初试牛刀:筛选绿苹果

public static List<Apple> filterGreenApples(List<Apple> inventory){
    List<Apple> result = new ArrayList<Apple>();
    for(Apple apple : inventory){
        if("green".equals(apple.getColor())){
          result.add(apple);
        }
    }
    return result;
}

把颜色作为参数

        public static List<Apple> filterGreenApples(List<Apple> inventory,String color){
                List<Apple> result = new ArrayList<Apple>();
                 for(Apple apple : inventory){
                 if(apple.getColor().equals(color)){
                     result.add(apple);
                 }
              }
              return result;
         }

现在需求修改只要改变color就okay,不用频繁的重写条件语句,造成重复代码的灾难了:

List<Apple> greenApples = filterApplesByColor(inventory, "green");
List<Apple> redApples = filterApplesByColor(inventory, "red");

如果需求形式做修改:比如换成,找出质量大于150g的苹果

这时又得加一个方法:

        public static List<Apple> filterGreenApples(List<Apple> inventory,String weight){
                List<Apple> result = new ArrayList<Apple>();
                 for(Apple apple : inventory){
                 if(apple.getWeight() > weight){
                     result.add(apple);
                 }
              }
              return result;
         }

引入了重复代码,很糟糕
软件工程原则:
不要重复自己(Don't Repeat Yourself)

每个属性都做筛选

        public static List<Apple> filterGreenApples(List<Apple> inventory,String weight){
                List<Apple> result = new ArrayList<Apple>();
                 for(Apple apple : inventory){
                 if(apple.getWeight() > weight){
                     result.add(apple);
                 }
              }
              return result;
         }

第三次:
行为参数化

public static List<Apple> filterApples(List<Apple> inventory, String color, int weight, boolean flag){
    List<Apple> result = new ArrayList<Apple>();
    for(Apple apple : inventory){
      if((flag && apple.getColor().equals(color)) || (!flag && apple.getWeight() > weight) ){
          result.add(apple);
      }
    }
    return result;
}

List<Apple> greenApples = filterApples(inventory,"green",0,true);
List<Apple> heavyApples = filterApples(inventory,"",150, false );
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容