一、为何关注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 );