Guava提供了一些接口和类,提供了一种类似函数式的编程风格。这个有一定的吸引力,但是远远没有Java8中lamada表达式配合函数式编程来的爽,而且Guava提供的这些接口的主要功能并不是在使用函数式编程风格,而是一下的使用方式。这些类/接口主要有:

  • Predicate接口:用来判断一个对象是否满足某些条件。
  • Predicates类:提供了对Predicate接口的操作方法。
  • Function接口:将一种类型的对象转换成另外一种类型的对象。
  • Functons类:提供了对Function接口的操作方法。

Predicate接口的主要作用是配合集合工具类进行过滤。
过滤出名字中含有”g”的所有名字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Predicate<String> nameFilter = new Predicate<String>(){
public boolean apply(String input){
if(Strings.isNullOrEmpty(input)){
return false;
}
if(input.contrains("g")){
return true;
}
return false;
}
}
List<String> names = Lists.newArrayList("gcl","guo","zs","hpx");
Collection<String> result = Collections2.filter(names, predicate);

说明:
在企业开发了经常会有集合的过滤操作,我们往往写一系列类继承自Predicate接口,来进行一系列的过滤。

Predicate常用的集合过滤方法:

集合类型 过滤方法说明
Collection Collections2.filter(Collection, Predicate)将一个collection按照predicate条件进行过滤返回另外一collection
Set Sets.filter(Set, Predicate) 将一个set按照predicate条件进行过滤返回另外一个set
Map Maps.filterKeys(Map, Predicate) Maps.filterValues(Map,Predicate) Maps.filterEntries(Map,Predicate) 将一个map按照predicate条件进行过滤返回另外一个map
Multimap Multimaps.filterKeys(Multimap,Predicate) Multimaps.filterValues(Multimap,Predicate) Multimaps.filterEntries(Multimap,Predicate) 将一个Multimap按照predicate条件进行过滤返回另外一个Multimap
SortedMap Maps.filterKeys(SortedMap,Predicate) Maps.filterValues(SortddMap, Predicate) Maps.filterEntries(SortedMap, Predicate) 将一个SortedMap按照predicate条件进行过滤返回另外一个SortedMap
Iterable Iterables.filter(Iterable, Predicate) 将一个可迭代的接口列表转换成另外一个可迭代的接口列表
Iterator Iterators.filter(Iterator, Predicate) 将一个迭代器按照predicate条件转换成另外一个迭代器

注意:
这里没有对List进行过滤的方法,如果想要过滤返回一个List集合可以采用如下方法:

1
List targetList = Lists.newArrayList(Collections2.filter(originList,predicate))

Predicates主要有两个作用:

  • 提供了常见使用的Predicate方法
  • 提供了对Predicate接口的操作方法

过滤出名字中包含字母“g”的所有名字

1
2
3
4
List<String> names = Lists.newArrayList("gcl","guo","zs","hpx");
List<String> filterNames = Lists.newArrayList(Collections2.filter(names,Predicates.contrainsPattern("g"))

排除所有名字为null的名字

1
2
3
List<String> names = Lists.newArrayList("gcl",null,"guo","zs",null,"hpx");
Collection<String> result = Collections.filter(names,Predicates.notNull())

Predicate的and/or/not操作:

1
2
3
4
5
Predicate andPredicate = Predicates.and(predicateA, predicateB);
Predicate orPredicate = Predicates.or(predicateA, predicateB);
Predicate andPredicate = Predicates.not(predicateA);

Function

Function可以用来将一种类型的对象转换成另外一种类型的对象,最常用的是用法是将一种类型的集合转换成另外一种类型的集合。
将名字集合中的所有名字后面都加上”baobao”二字(学习支付宝)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Function<String,String> transFunction = new Function(String,String)(){
public String apply(input){
return input+"baobao";
}
}
List<String> names = Lists.newArrayList("gcl","guo","zs","hpx");
List<String> result = Lists.transform(names,transFunction);

Function常用的集合转换方法:

集合类型 过滤方法说明
Collection Collections2.transform(Collection, Function) 将一个collection按照function函数转换成另外一个collection
List Lists.transform(List, Function) 将一个list按照function函数转换成另外一个list
Map Maps.transformValues(Map,Function) Maps.transformEntries(Map,EntryTransformer) 将一个map按照function函数转换成另外一个map
Multimap Multimaps.transformValues(Multimap,Function) Multimaps.transformEntries(Multimap,EntryTransformer) 将一个Multimap按照function函数转换成另外一个Multimap
Iterator Iterators.transform(Iterator, Function) 将一个迭代器按照function函数转换成另外一个迭代器
Iterable Iterables.transform(Iterable, Function) 将一个可迭代接口列表按照function函数转换成另外一个可迭代接口列表

注意:这里没有对Set进行转换的方法,如果需要转换返回一个Set集合可以采用如下的方法:

1
Set targetSet = Sets.newHashSet(Collectios2.transform(originSet,function))

Functions

Functions是用来对Function接口进行操作:
例如:想讲名字的列表转换成字符长度的列表,然后判断字符长度是否是偶数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Function<String,Integer> f1 = new Function<String,Integer>(){
@Override
public Integer apply(String input) {
return input.length();
}
};
Function<Integer,Boolean> f2 = new Function<Integer,Boolean>(){
@Override
public Boolean apply(Integer input) {
return input % 2 == 0;
}
};
List<String> names = Lists.newArrayList("John", "Jane", "Adam", "Tom");
List<Boolean> result = Lists.transform(names, Functions.compose(f2, f1));

将名字中含有字母g的名字,转换成字母的长度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean apply(String input) {
return input.contrains("a");
}
};
Function<String, Integer> func = new Function<String,Integer>(){
@Override
public Integer apply(String input) {
return input.length();
}
};
List<String> names = Lists.newArrayList("gcl","guo","zs","hpx");
List<Integer> result = FluentIterable.from(names)
.filter(predicate)
.transform(func)
.toList();