##什么是函数式编程
函数式编程是种编程典范,它将电脑运算视为函数的计算。函数编程语言最重要的基础是 λ 演算(lambda calculus)。而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。和指令式编程相比,函数式编程强调函数的计算比指令的执行重要。和过程化编程相比,函数式编程里,函数的计算可随时调用。
##Guava中的函数式编程
为了支持函数式编程,Guava提供了下面这两个接口:
public interface Function<F, T> {
@Nullable T apply(@Nullable F input);
}
public interface Predicate<T> {
boolean apply(@Nullable T input);
}
举个例子:在一群People对象中,找到年龄大于20的People
通常做法:
List
oldPeople = new ArrayList ();
for (Person person : people) {if (person.getAge() >= 20) { oldPeople.add(person); }
}
在Guava中提供了filter模式,filter即从一个集合中根据一个条件筛选元素。
找出age大于20的
List<Person> oldPeople = Lists.newArrayList(Collections2.filter(people, new Predicate<Person>() { public boolean apply(Person person) { return person.getAge() >= 20; } }));
找出name中含有字符w的
List<Person> oldPeople = Lists.newArrayList(Collections2.filter(people, new Predicate<Person>() { public boolean apply(Person person) { return person.getName().contains("w"); } }));
找出age>20并且name中含有字符w的人
// 一般大家都会这么写,当然这种写法是可以的 List<Person> oldPersons = Lists.newArrayList(Collections2.filter(persons, new Predicate<Person>() { public boolean apply(Person person) { return person.getAge() >= 20 && person.getName().contains("w"); } }));
这样写的话就有一定的代码重复,因为之前我们已经写了两个Predicate来分别实现这两个条件判断,能不能重用之前的Predicate那?答案是能。 我们首先将之前生成年龄判断和名称判断的两个Predicate抽成方法。
private Predicate<Person> ageBiggerThan(final int age) {
return new Predicate<Person>() {
public boolean apply(Person person) {
return person.getAge() >= age;
}
};
}
private Predicate<Person> nameContains(final String str) {
return new Predicate<Person>() {
public boolean apply(Person person) {
return person.getName().contains(str);
}
};
}
//而我们的结果其实就是这两个Predicate相与。Guava给我们提供了and方法,用于对一组Predicate求与。
List<Person> filteredPeople = Lists.newArrayList(Collections2.filter(people, Predicates.and(ageBiggerThan(20), nameContains("w"))));
##JDK8中的函数式编程
在上面的例子中:
在一群People对象中,找到年龄大于20的People
List
filteredPeople = persons.stream().filter(p -> p.getAge() >= 20).collect(Collectors.toList()); 找出name中含有字符w的
List<Person> filteredPeople = persons.stream().filter(p -> p.getName().contains("w")).collect(Collectors.toList());
##总结
- 无法升级jdk版本的项目,推荐使用guava
guava作为jdk8最好的替代品,是值得使用的
- 可以平稳升级jdk的项目,推荐使用jdk8
jdk8天生的优势,注定它优于guava,再加上后来引入的lambda表达式,使jdk8的语法更加优美
- jdk8出生于guava之后,所以说,jdk8很多地方都是借鉴于guava