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 filterGreenApples(List inventory ){
   List result = new ArrayList<>();
   for(Apple apple : inventory){
      if("green".equals(apple.getColor())){
         result.add(apple);
      }
   }
   return result;
}

//仅仅选出重的苹果
public static List filterGreenApples(List inventory ){
   List 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{
    boolean test(T t);
}

//方法作为谓词传递进去
static List filterApples(List inventory,Predicate p){
   List 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参数值,谓词在数学上用来形容类似函数的东西

从传递方法到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  Collection filter(Collection c , Predicate p);
filterApples(inventory,(Apple a) -> a.getWeight() > 150);
filter(inventory,(Apple a) -> a.getWeight() > 150);

Map> transactionsByCurrencies = new HashMap<>();
for(Transaction transaction : transactions){
   if(transaction.getPrice() > 1000){
      Currency currency = transaction.getCurrency();
      List 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> transactionsForCurrencies = transaction.stream().filter(
(Transaction t) -> t.getPrice() > 1000).collect(groupingBy(Transaction :: getCurrency));

并行处理

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

默认方法:

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

List 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 filterGreenApples(List inventory){
    List result = new ArrayList();
    for(Apple apple : inventory){
        if("green".equals(apple.getColor())){
          result.add(apple);
        }
    }
    return result;
}

把颜色作为参数

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

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

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

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

这时又得加一个方法:

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

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

每个属性都做筛选

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

第三次:
行为参数化

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

List greenApples = filterApples(inventory,"green",0,true);
List heavyApples = filterApples(inventory,"",150, false );

你可能感兴趣的:(Java8 in action)