目前Java版本已经更新到11,所以我们现在学一下Java8?。
一、基础
- 背景
Unix系统中我们可以使用cat命令将两个文件连接起来创建一个流,tr命令会转换流中的字符,sort会对流中的命令进行排序,而tail -n 则可以给出流的后n行。我们可以使用管道 | 将这些程序连在一起。
cat a.log b.log | tr "[A-Z]" "[a-z]" | sort | tail -10
该命令会将a 、b 两个文件合在一起,然后将字母转换为小写字母,然后按照字典排序之后打印出最后的10个单词。
- Java8 中提供的 java.util.stream中添加的Stream API
public interface Stream<T> extends BaseStream<T, Stream<T>> {}
Stream< T > 是一系列T 类型的项目,他可以像上面背景中提到的一样
API中的很多方法可以连接起来像流水线一般来对数据进行处理。
- 经过这个操作,我们可以使用“把这种流转换成另外一种流”的思想去写代码,类似于数据库查询语言【可以很好地利用多核】。
- 我们还可以将方法作为参数传递给另一个方法【行文参数化】
- 没有共享的可变数据。
- 默认方法【接口中的默认方法】在Collection接口添加默认方法,实现让List 可以调用stream或者parallelStream。
- NULL值处理以及模式匹配。
二、参数化传递代码
一般的话我们都是通过实现接口的方式来满足不同的功能。
- 比我我们现在有个经常会改变的需求,所以我们需要定义一些尽量满足这些需求的代码,我们可以通过定义一个接口,然后定义一些类来实现该接口。
- 比如说
//定义自己的接口
interface IPredicate{
public boolean test(Apple a);
}
- 然后定义一些类实现它:
class IPredicateImplOne implements IPredicate{
public boolean test(Apple apple){
//doSomething
return ?;
}
}
class IPredicateImplTwo implements IPredicate{
public boolean test(Apple apple){
//doSomething
return ?;
}
}
- 然后我们定义一个方法:
public static List<T> filter(List<T> somes, IPredicate ip){
List<T> result = new ArrayList<>();
for(T : somes){
if(ip.test(t)){
result.add(t);
}
}
return result;
}
- 我们在main方法中如此使用:
public static void main(String ... args){
List<T> somes = Arrays.asList(new T(), new T(), new T());
List<T> doSomeOne = filter(somes, new IPredicateImplOne());
System.out.println(doSomeOne);
List<T> doSomeTwo = filter(somes, new IPredicateImplTwo());
System.out.println(doSomeTwo);
//使用匿名内部类的方式
List<T> doSomeThree = filter(somes, new IPredicate() {
public boolean test(T t){
//doSomeThree
return ?;
}
});
System.out.println(doSomeThree);
}
- 我们可以使用Lamada表达式来替换这些繁琐的代码:
public static void main(String[] args) {
List<T> somes = Arrays.asList(new T(), new T(), new T());
System.out.println(somes.stream().filter(a -> //doSome).filter(a -> //doSome).collect(Collectors.toList()));
}
- Java 8 中给我们提供了 Predicate< T> 接口这样我们在使用中就不用定义自己的接口了。
强烈推荐看一下 Java8 in Action这本书比较有趣。