# 4-函數式編程
# 4-函數式編程
[原文鏈接](http://code.google.com/p/guava-libraries/wiki/FunctionalExplained) [譯文鏈接](http://ifeve.com/google-guava-functional) 譯者:沈義揚,校對:丁一
## 注意事項
截至JDK7,Java中也只能通過笨拙冗長的匿名類來達到近似函數式編程的效果。預計JDK8中會有所改變,但Guava現在就想給JDK5以上用戶提供這類支持。
過度使用Guava函數式編程會導致冗長、混亂、可讀性差而且低效的代碼。這是迄今為止最容易(也是最經常)被濫用的部分,如果你想通過函數式風格達成一行代碼,致使這行代碼長到荒唐,Guava團隊會淚流滿面。
比較如下代碼:
```
<pre class="calibre11">```
Function<String, Integer> lengthFunction = new Function<String, Integer>() {
public Integer apply(String string) {
return string.length();
}
};
Predicate<String> allCaps = new Predicate<String>() {
public boolean apply(String string) {
return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string);
}
};
Multiset<Integer> lengths = HashMultiset.create(
Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction));
```
```
或FluentIterable的版本
```
<pre class="calibre11">```
Multiset<Integer> lengths = HashMultiset.create(
FluentIterable.from(strings)
.filter(new Predicate<String>() {
public boolean apply(String string) {
return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string);
}
})
.transform(new Function<String, Integer>() {
public Integer apply(String string) {
return string.length();
}
}));
```
```
還有
```
<pre class="calibre11">```
Multiset<Integer> lengths = HashMultiset.create();
for (String string : strings) {
if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) {
lengths.add(string.length());
}
}
```
```
即使用了靜態導入,甚至把Function和Predicate的聲明放到別的文件,第一種代碼實現仍然不簡潔,可讀性差并且效率較低。
截至JDK7,命令式代碼仍應是默認和第一選擇。不應該隨便使用函數式風格,除非你絕對確定以下兩點之一:
- 使用函數式風格以后,整個工程的代碼行會凈減少。在上面的例子中,函數式版本用了11行, 命令式代碼用了6行,把函數的定義放到另一個文件或常量中,并不能幫助減少總代碼行。
- 為了提高效率,轉換集合的結果需要懶視圖,而不是明確計算過的集合。此外,確保你已經閱讀和重讀了Effective Java的第55條,并且除了閱讀本章后面的說明,你還真正做了性能測試并且有測試數據來證明函數式版本更快。
請務必確保,當使用Guava函數式的時候,用傳統的命令式做同樣的事情不會更具可讀性。嘗試把代碼寫下來,看看它是不是真的那么糟糕?會不會比你想嘗試的極其笨拙的函數式 更具可讀性。
## Functions\[函數\]和Predicates\[斷言\]
本節只討論直接與Function和Predicate打交道的Guava功能。一些其他工具類也和”函數式風格”相關,例如[`Iterables.concat(Iterable<Iterable>)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#concat%28java.lang.Iterable%29),和其他用常量時間返回視圖的方法。嘗試看看[2.3節的集合工具類](http://ifeve.com/google-guava-collectionutilities)。
Guava提供兩個基本的函數式接口:
- Function<A, B>,它聲明了單個方法B apply(A input)。Function對象通常被預期為引用透明的——沒有副作用——并且引用透明性中的”相等”語義與equals一致,如a.equals(b)意味著function.apply(a).equals(function.apply(b))。
- Predicate<T>,它聲明了單個方法boolean apply(T input)。Predicate對象通常也被預期為無副作用函數,并且”相等”語義與equals一致。
### 特殊的斷言
字符類型有自己特定版本的Predicate——[`CharMatcher`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/CharMatcher.html),它通常更高效,并且在某些需求方面更有用。CharMatcher實現了Predicate<Character>,可以當作Predicate一樣使用,要把Predicate轉成CharMatcher,可以使用[`CharMatcher.forPredicate`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6common/base/CharMatcher.html#forPredicate%28com.google.common.base.Predicate%29)。更多細節請參考第6章-字符串處理。
此外,對可比較類型和基于比較邏輯的Predicate,Range類可以滿足大多數需求——它表示一個不可變區間。Range類實現了Predicate,用以判斷值是否在區間內。例如,Range.atMost(2)就是個完全合法的Predicate<Integer>。更多使用Range的細節請參照第8章。
### 操作Functions和Predicates
[Functions](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/Functions.html)提供簡便的Function構造和操作方法,包括:
[`forMap(Map<A, B>)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Functions.html#forMap%28java.util.Map%29)[`compose(Function<B, C>, Function<A, B>)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29)[`constant(T)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Functions.html#constant%28E%29)[`identity()`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Functions.html#identity%28%29)[`toStringFunction()`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Functions.html#toStringFunction%28%29)細節請參考Javadoc。
相應地,[Predicates](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/Predicates.html)提供了更多構造和處理Predicate的方法,下面是一些例子:
[`instanceOf(Class)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#instanceOf%28java.lang.Class%29)[`assignableFrom(Class)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#assignableFrom%28java.lang.Class%29)[`contains(Pattern)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#contains%28java.util.regex.Pattern%29)[`in(Collection)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#in%28java.util.Collection%29)[`isNull()`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#isNull%28%29)[`alwaysFalse()`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#alwaysFalse%28%29)[`alwaysTrue()`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#alwaysTrue%28%29)[`equalTo(Object)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#equalTo%28T%29)[`compose(Predicate, Function)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#compose%28com.google.common.base.Predicate,%20com.google.common.base.Function%29)[`and(Predicate...)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#and%28com.google.common.base.Predicate...%29)[`or(Predicate...)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#or%28com.google.common.base.Predicate...%29)[`not(Predicate)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicates.html#not%28com.google.common.base.Predicate%29)細節請參考Javadoc。
## 使用函數式編程
Guava提供了很多工具方法,以便用Function或Predicate操作集合。這些方法通常可以在集合工具類找到,如Iterables,Lists,Sets,Maps,Multimaps等。
### 斷言
斷言的最基本應用就是過濾集合。所有Guava過濾方法都返回”視圖”——*譯者注:即并非用一個新的集合表示過濾,而只是基于原集合的視圖*。
**集合類型****過濾方法**Iterable[`Iterables.filter(Iterable, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#filter%28java.lang.Iterable,%20com.google.common.base.Predicate%29)[`FluentIterable.filter(Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/co%E2%80%A6common/collect/FluentIterable.html#filter%28com.google.common.base.Predicate%29)Iterator[`Iterators.filter(Iterator, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#filter%28java.util.Iterator,%20com.google.common.base.Predicate%29)Collection[`Collections2.filter(Collection, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Collections2.html#filter%28java.util.Collection,%20com.google.common.base.Predicate%29)Set[`Sets.filter(Set, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#filter%28java.util.Set,%20com.google.common.base.Predicate%29)SortedSet[`Sets.filter(SortedSet, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#filter%28java.util.SortedSet,%20com.google.common.base.Predicate%29)Map[`Maps.filterKeys(Map, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#filterKeys%28java.util.Map,%20com.google.common.base.Predicate%29)[`Maps.filterValues(Map, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#filterValues%28java.util.Map,%20com.google.common.base.Predicate%29)[`Maps.filterEntries(Map, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#filterEntries%28java.util.Map,%20com.google.common.base.Predicate%29)SortedMap[`Maps.filterKeys(SortedMap, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#filterKeys%28java.util.SortedMap,%20com.google.common.base.Predicate%29)[`Maps.filterValues(SortedMap, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#filterValues%28java.util.SortedMap,%20com.google.common.base.Predicate%29)[`Maps.filterEntries(SortedMap, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#filterEntries%28java.util.SortedMap,%20com.google.common.base.Predicate%29)Multimap[`Multimaps.filterKeys(Multimap, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6ommon/collect/Multimaps.html#filterKeys%28com.google.common.collect.Multimap,%20com.google.common.base.Predicate%29)[`Multimaps.filterValues(Multimap, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6mon/collect/Multimaps.html#filterValues%28com.google.common.collect.Multimap,%20com.google.common.base.Predicate%29)[`Multimaps.filterEntries(Multimap, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6on/collect/Multimaps.html#filterEntries%28com.google.common.collect.Multimap,%20com.google.common.base.Predicate%29)\*List的過濾視圖被省略了,因為不能有效地支持類似get(int)的操作。請改用Lists.newArrayList(Collections2.filter(list, predicate))做拷貝過濾。
除了簡單過濾,Guava另外提供了若干用Predicate處理Iterable的工具——通常在[`Iterables`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/Iterables.html)工具類中,或者是[`FluentIterable`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html)的”fluent”(鏈式調用)方法。
**Iterables\*\***方法簽名\*\***說明****另請參見**[`boolean all(Iterable, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#all%28java.lang.Iterable,%20com.google.common.base.Predicate%29)是否所有元素滿足斷言?懶實現:如果發現有元素不滿足,不會繼續迭代[`Iterators.all(Iterator, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#all%28java.util.Iterator,%20com.google.common.base.Predicate%29)[`FluentIterable.allMatch(Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/co%E2%80%A6mmon/collect/FluentIterable.html#allMatch%28com.google.common.base.Predicate%29)[`boolean any(Iterable, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#any%28java.lang.Iterable,%20com.google.common.base.Predicate%29)是否有任意元素滿足元素滿足斷言?懶實現:只會迭代到發現滿足的元素[`Iterators.any(Iterator, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#any%28java.util.Iterator,%20com.google.common.base.Predicate%29)[`FluentIterable.anyMatch(Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/co%E2%80%A6mmon/collect/FluentIterable.html#anyMatch%28com.google.common.base.Predicate%29)[`T find(Iterable, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#find%28java.lang.Iterable,%20com.google.common.base.Predicate%29)循環并返回**一個**滿足元素滿足斷言的元素,如果沒有則拋出NoSuchElementException[`Iterators.find(Iterator, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#find%28java.util.Iterator,%20com.google.common.base.Predicate%29) [`Iterables.find(Iterable, Predicate, T default)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#find%28java.lang.Iterable,%20com.google.common.base.Predicate,%20T%29) [`Iterators.find(Iterator, Predicate, T default)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#find%28java.util.Iterator,%20com.google.common.base.Predicate,%20T%29)[`Optional<T> tryFind(Iterable, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#tryFind%28java.lang.Iterable,%20com.google.common.base.Predicate%29)返回**一個**滿足元素滿足斷言的元素,若沒有則返回`O`ptional.absent()[`Iterators.find(Iterator, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#find%28java.util.Iterator,%20com.google.common.base.Predicate%29) [`Iterables.find(Iterable, Predicate, T default)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#find%28java.lang.Iterable,%20com.google.common.base.Predicate,%20T%29) [`Iterators.find(Iterator, Predicate, T default)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#find%28java.util.Iterator,%20com.google.common.base.Predicate,%20T%29)[`indexOf(Iterable, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#indexOf%28java.lang.Iterable,%20com.google.common.base.Predicate%29)返回第一個滿足元素滿足斷言的元素索引值,若沒有返回-1[`Iterators.indexOf(Iterator, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#indexOf%28java.util.Iterator,%20com.google.common.base.Predicate%29)[`removeIf(Iterable, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#removeIf%28java.lang.Iterable,%20com.google.common.base.Predicate%29)移除所有滿足元素滿足斷言的元素,實際調用Iterator.remove()方法[`Iterators.removeIf(Iterator, Predicate)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#removeIf%28java.util.Iterator,%20com.google.common.base.Predicate%29)### 函數
到目前為止,函數最常見的用途為轉換集合。同樣,所有的Guava轉換方法也返回原集合的視圖。
**集合類型****轉換\*\***方法\*\*Iterable[`Iterables.transform(Iterable, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#transform%28java.lang.Iterable,%20com.google.common.base.Function%29)[`FluentIterable.transform(Function)`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/co%E2%80%A6mmon/collect/FluentIterable.html#transform%28com.google.common.base.Function%29)Iterator[`Iterators.transform(Iterator, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html#transform%28java.util.Iterator,%20com.google.common.base.Function%29)Collection[`Collections2.transform(Collection, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Collections2.html#transform%28java.util.Collection,%20com.google.common.base.Function%29)List[`Lists.transform(List, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#transform%28java.util.List,%20com.google.common.base.Function%29)Map\*[`Maps.transformValues(Map, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#transformValues%28java.util.Map,%20com.google.common.base.Function%29)[`Maps.transformEntries(Map, EntryTransformer)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#transformEntries%28java.util.Map,%20com.google.common.collect.Maps.EntryTransformer%29)SortedMap\*[`Maps.transformValues(SortedMap, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#transformValues%28java.util.SortedMap,%20com.google.common.base.Function%29)[`Maps.transformEntries(SortedMap, EntryTransformer)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#transformEntries%28java.util.SortedMap,%20com.google.common.collect.Maps.EntryTransformer%29)Multimap\*[`Multimaps.transformValues(Multimap, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6/collect/Multimaps.html#transformValues%28com.google.common.collect.Multimap,%20com.google.common.base.Function%29)[`Multimaps.transformEntries(Multimap, EntryTransformer)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6collect/Multimaps.html#transformEntries%28com.google.common.collect.Multimap,%20com.google.common.collect.Maps.EntryTransformer%29)ListMultimap\*[`Multimaps.transformValues(ListMultimap, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6lect/Multimaps.html#transformValues%28com.google.common.collect.ListMultimap,%20com.google.common.base.Function%29)[`Multimaps.transformEntries(ListMultimap, EntryTransformer)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6ect/Multimaps.html#transformEntries%28com.google.common.collect.ListMultimap,%20com.google.common.collect.Maps.EntryTransformer%29)Table[`Tables.transformValues(Table, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6common/collect/Tables.html#transformValues%28com.google.common.collect.Table,%20com.google.common.base.Function%29)\*Map和[`Multimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimap.html)有特殊的方法,其中有個[`EntryTransformer<K, V1, V2>`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.EntryTransformer.html)參數,它可以使用舊的鍵值來計算,并且用計算結果替換舊值。
\*對Set的轉換操作被省略了,因為不能有效支持contains(Object)操作——*譯者注:懶視圖實際上不會全部計算轉換后的**Set**元素,因此不能高效地支持**contains(Object)**。*請改用Sets.newHashSet(Collections2.transform(set, function))進行拷貝轉換。
```
<pre class="calibre11">```
List<String> names;
Map<String, Person> personWithName;
List<Person> people = Lists.transform(names, Functions.forMap(personWithName));
ListMultimap<String, String> firstNameToLastNames;
// maps first names to all last names of people with that first name
ListMultimap<String, String> firstNameToName = Multimaps.transformEntries(firstNameToLastNames,
new EntryTransformer<String, String, String> () {
public String transformEntry(String firstName, String lastName) {
return firstName + " " + lastName;
}
});
```
```
可以組合Function使用的類包括:
Ordering[`Ordering.onResultOf(Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6le/common/collect/Ordering.html#onResultOf%28com.google.common.base.Function%29)Predicate[`Predicates.compose(Predicate, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/Predicates.html#compose%28com.google.common.base.Predicate,%20com.google.common.base.Function%29)Equivalence[`Equivalence.onResultOf(Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6le/common/base/Equivalence.html#onResultOf%28com.google.common.base.Function%29)Supplier[`Suppliers.compose(Function, Supplier)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/Suppliers.html#compose%28com.google.common.base.Function,%20com.google.common.base.Supplier%29)Function[`Functions.compose(Function, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/Functions.html#compose%28com.google.common.base.Function,%20com.google.common.base.Function%29)此外,[ListenableFuture](http://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained) API支持轉換ListenableFuture。Futures也提供了接受[`AsyncFunction`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/util/concurrent/AsyncFunction.html)參數的方法。AsyncFunction是Function的變種,它允許異步計算值。
[`Futures.transform(ListenableFuture, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6/Futures.html#transform%28com.google.common.util.concurrent.ListenableFuture,%20com.google.common.base.Function%29)[`Futures.transform(ListenableFuture, Function, Executor)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6/Futures.html#transform%28com.google.common.util.concurrent.ListenableFuture,%20com.google.common.base.Function,%20java.util.concurrent.Executor%29)[`Futures.transform(ListenableFuture, AsyncFunction)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6/Futures.html#transform%28com.google.common.util.concurrent.ListenableFuture,%20com.google.common.util.concurrent.AsyncFunction%29)[`Futures.transform(ListenableFuture, AsyncFunction, Executor)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/%E2%80%A6/Futures.html#transform%28com.google.common.util.concurrent.ListenableFuture,%20com.google.common.util.concurrent.AsyncFunction,%20java.util.concurrent.Executor%29)
- 介紹
- Google Guava官方教程(中文版)
- 1-基本工具
- 1.1-使用和避免null
- 1.2-前置條件
- 1.3-常見Object方法
- 1.4-排序: Guava強大的”流暢風格比較器”
- 1.5-Throwables:簡化異常和錯誤的傳播與檢查
- 2-集合
- 2.1-不可變集合
- 2.2-新集合類型
- 2.3-強大的集合工具類:java.util.Collections中未包含的集合工具
- 2.4-集合擴展工具類
- 3-緩存
- 4-函數式編程
- 5-并發
- 5.1-google Guava包的ListenableFuture解析
- 5.2-Google-Guava Concurrent包里的Service框架淺析
- 6-字符串處理:分割,連接,填充
- 7-原生類型
- 9-I/O
- 10-散列
- 11-事件總線
- 12-數學運算
- 13-反射