# 2.3-強大的集合工具類:java.util.Collections中未包含的集合工具
[原文鏈接](http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained)?[譯文鏈接](http://ifeve.com/google-guava-collectionutilities)?譯者:沈義揚,校對:丁一
_尚未完成: Queues, Tables工具類_
任何對JDK集合框架有經驗的程序員都熟悉和喜歡[`java.util.Collections`](http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html)包含的工具方法。Guava沿著這些路線提供了更多的工具方法:適用于所有集合的靜態方法。這是Guava最流行和成熟的部分之一。
我們用相對直觀的方式把工具類與特定集合接口的對應關系歸納如下:
| **集合接口** | **屬于****JDK****還是****Guava** | **對應的****Guava****工具類** |
|:--- |:--- |:--- |
| Collection | JDK | [`Collections2`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Collections2.html):不要和java.util.Collections混淆 |
| List | JDK | [`Lists`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Lists.html) |
| Set | JDK | [`Sets`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Sets.html) |
| SortedSet | JDK | [`Sets`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Sets.html) |
| Map | JDK | [`Maps`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Maps.html) |
| SortedMap | JDK | [`Maps`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Maps.html) |
| Queue | JDK | [`Queues`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Queues.html) |
| [Multiset](http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset) | Guava | [`Multisets`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multisets.html) |
| [Multimap](http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap) | Guava | [`Multimaps`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimaps.html) |
| [BiMap](http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap) | Guava | [`Maps`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html) |
| [Table](http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Table) | Guava | [`Tables`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Tables.html) |
_在找類似轉化、過濾的方法?請看第四章,函數式風格。_
## 靜態工廠方法
在JDK 7之前,構造新的范型集合時要討厭地重復聲明范型:
```
List<TypeThatsTooLongForItsOwnGood> list = new ArrayList<TypeThatsTooLongForItsOwnGood>();
```
我想我們都認為這很討厭。因此Guava提供了能夠推斷范型的靜態工廠方法:
```
List<TypeThatsTooLongForItsOwnGood> list = Lists.newArrayList();
Map<KeyType, LongishValueType> map = Maps.newLinkedHashMap();
```
可以肯定的是,JDK7版本的鉆石操作符(<>)沒有這樣的麻煩:
```
List<TypeThatsTooLongForItsOwnGood> list = new ArrayList<>();
```
但Guava的靜態工廠方法遠不止這么簡單。用工廠方法模式,我們可以方便地在初始化時就指定起始元素。
```
Set<Type> copySet = Sets.newHashSet(elements);
List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");
```
此外,通過為工廠方法命名(Effective Java第一條),我們可以提高集合初始化大小的可讀性:
```
List<Type> exactly100 = Lists.newArrayListWithCapacity(100);
List<Type> approx100 = Lists.newArrayListWithExpectedSize(100);
Set<Type> approx100Set = Sets.newHashSetWithExpectedSize(100);
```
確切的靜態工廠方法和相應的工具類一起羅列在下面的章節。
注意:Guava引入的新集合類型沒有暴露原始構造器,也沒有在工具類中提供初始化方法。而是直接在集合類中提供了靜態工廠方法,例如:
```
Multiset<String> multiset = HashMultiset.create();
```
## Iterables
在可能的情況下,Guava提供的工具方法更偏向于接受Iterable而不是Collection類型。在Google,對于不存放在主存的集合——比如從數據庫或其他數據中心收集的結果集,因為實際上還沒有攫取全部數據,這類結果集都不能支持類似size()的操作 ——通常都不會用Collection類型來表示。
因此,很多你期望的支持所有集合的操作都在[`Iterables`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html)類中。大多數Iterables方法有一個在[Iterators](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterators.html)類中的對應版本,用來處理Iterator。
截至Guava 1.2版本,Iterables使用`[FluentIterable](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html)類`進行了補充,它包裝了一個Iterable實例,并對許多操作提供了”fluent”(鏈式調用)語法。
下面列出了一些最常用的工具方法,但更多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) | 串聯多個iterables的懶視圖* | [`concat(Iterable...)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#concat%28java.lang.Iterable...%29) |
|:--- |:--- |:--- |
| [`frequency(Iterable, Object)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#frequency%28java.lang.Iterable, java.lang.Object%29) | 返回對象在iterable中出現的次數 | 與Collections.frequency (Collection, ? Object)比較;[Multiset](http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset) |
| [`partition(Iterable, int)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#partition%28java.lang.Iterable, int%29) | 把iterable按指定大小分割,得到的子集都不能進行修改操作 | [`Lists.partition(List, int)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#partition%28java.util.List, int%29);[`paddedPartition(Iterable, int)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#paddedPartition%28java.lang.Iterable, int%29) |
| [`getFirst(Iterable, T default)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#getFirst%28java.lang.Iterable, T%29) | 返回iterable的第一個元素,若iterable為空則返回默認值 | 與Iterable.iterator(). next()比較;[`FluentIterable.first()`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html#first%28%29) |
| [`getLast(Iterable)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#getLast%28java.lang.Iterable%29) | 返回iterable的最后一個元素,若iterable為空則拋出NoSuchElementException | [`getLast(Iterable, T default)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#getLast%28java.lang.Iterable, T%29);
[`FluentIterable.last()`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html#last%28%29) |
| [`elementsEqual(Iterable, Iterable)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#elementsEqual%28java.lang.Iterable, java.lang.Iterable%29) | 如果兩個iterable中的所有元素相等且順序一致,返回true | 與List.equals(Object)比較 |
| [`unmodifiableIterable(Iterable)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…ogle/common/collect/Iterables.html#unmodifiableIterable%28java.lang.Iterable%29) | 返回iterable的不可變視圖 | 與Collections. unmodifiableCollection(Collection)比較 |
| [`limit(Iterable, int)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#limit%28java.lang.Iterable, int%29) | 限制iterable的元素個數限制給定值 | [`FluentIterable.limit(int)`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html#limit%28int%29) |
| [`getOnlyElement(Iterable)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#getOnlyElement%28java.lang.Iterable%29) | 獲取iterable中唯一的元素,如果iterable為空或有多個元素,則快速失敗 | [`getOnlyElement(Iterable, T default)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#getOnlyElement%28java.lang.Iterable, T%29) |
_*譯者注:懶視圖意味著如果還沒訪問到某個iterable中的元素,則不會對它進行串聯操作。_
```
Iterable<Integer> concatenated = Iterables.concat(
Ints.asList(1, 2, 3),
Ints.asList(4, 5, 6)); // concatenated包括元素 1, 2, 3, 4, 5, 6
String lastAdded = Iterables.getLast(myLinkedHashSet);
String theElement = Iterables.getOnlyElement(thisSetIsDefinitelyASingleton);
//如果set不是單元素集,就會出錯了!
```
### 與Collection方法相似的工具方法
通常來說,Collection的實現天然支持操作其他Collection,但卻不能操作Iterable。
下面的方法中,如果傳入的Iterable是一個Collection實例,則實際操作將會委托給相應的Collection接口方法。例如,往Iterables.size方法傳入是一個Collection實例,它不會真的遍歷iterator獲取大小,而是直接調用Collection.size。
| **方法** | **類似的****Collection****方法** | **等價的****FluentIterable****方法** |
|:--- |:--- |:--- |
| [`addAll(Collection addTo, ? Iterable toAdd)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#addAll%28java.util.Collection, java.lang.Iterable%29) | Collection.addAll(Collection) |
| [`contains(Iterable, Object)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#contains%28java.lang.Iterable, java.lang.Object%29) | Collection.contains(Object) | [`FluentIterable.contains(Object)`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html#contains%28java.lang.Object%29) |
| [`removeAll(Iterable ? removeFrom, Collection toRemove)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#removeAll%28java.lang.Iterable, java.util.Collection%29) | Collection.removeAll(Collection) |
| [`retainAll(Iterable ? removeFrom, Collection toRetain)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#retainAll%28java.lang.Iterable, java.util.Collection%29) | Collection.retainAll(Collection) |
| [`size(Iterable)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#size%28java.lang.Iterable%29) | Collection.size() | [`FluentIterable.size()`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html#size%28%29) |
| [`toArray(Iterable, Class)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#toArray%28java.lang.Iterable, java.lang.Class%29) | Collection.toArray(T[]) | [`FluentIterable.toArray(Class)`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html#toArray%28java.lang.Class%29) |
| [`isEmpty(Iterable)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#isEmpty%28java.lang.Iterable%29) | Collection.isEmpty() | [`FluentIterable.isEmpty()`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html#isEmpty%28%29) |
| [`get(Iterable, int)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#get%28java.lang.Iterable, int%29) | List.get(int) | [`FluentIterable.get(int)`](http://docs.guava-libraries.googlecode.com/git-%20history/release12/javadoc/com/google/common/collect/FluentIterable.html#get%28int%29) |
| [`toString(Iterable)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#toString%28java.lang.Iterable%29) | Collection.toString() | [`FluentIterable.toString()`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html#toString%28%29) |
### FluentIterable
除了上面和第四章提到的方法,FluentIterable還有一些便利方法用來把自己拷貝到不可變集合
| ImmutableList |
|:--- |:--- |
| ImmutableSet | [`toImmutableSet()`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/com/google/common/collect/FluentIterable.html#toImmutableSet%28%29) |
| ImmutableSortedSet | [`toImmutableSortedSet(Comparator)`](http://docs.guava-libraries.googlecode.com/git-history/release12/javadoc/co…mmon/collect/FluentIterable.html#toImmutableSortedSet%28java.util.Comparator%29) |
## Lists
除了靜態工廠方法和函數式編程方法,[`Lists`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Lists.html)為List類型的對象提供了若干工具方法。
| **方法** | **描述** |
|:--- |:--- |
| [`partition(List, int)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#partition%28java.util.List, int%29) | 把List按指定大小分割 |
| [`reverse(List)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#reverse%28java.util.List%29) | 返回給定List的反轉視圖。注: 如果List是不可變的,考慮改用[`ImmutableList.reverse()`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/ImmutableList.html#reverse%28%29)。 |
```
List countUp = Ints.asList(1, 2, 3, 4, 5);
List countDown = Lists.reverse(theList); // {5, 4, 3, 2, 1}
List<List> parts = Lists.partition(countUp, 2);//{{1,2}, {3,4}, {5}}
```
### 靜態工廠方法
Lists提供如下靜態工廠方法:
| **具體實現類型** | **工廠方法** |
|:--- |:--- |
| ArrayList | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#newArrayList%28%29), [with elements](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#newArrayList%28E...%29), [from `Iterable`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#newArrayList%28java.lang.Iterable%29), [with exact capacity](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#newArrayListWithCapacity%28int%29), [with expected size](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#newArrayListWithExpectedSize%28int%29), [from `Iterator`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#newArrayList%28java.util.Iterator%29) |
| LinkedList | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#newLinkedList%28%29), [from `Iterable`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Lists.html#newLinkedList%28java.lang.Iterable%29) |
## Sets
[`Sets`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Sets.html)工具類包含了若干好用的方法。
### 集合理論方法
我們提供了很多標準的集合運算(Set-Theoretic)方法,這些方法接受Set參數并返回[`SetView`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.SetView.html),可用于:
* 直接當作Set使用,因為SetView也實現了Set接口;
* 用[`copyInto(Set)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.SetView.html#copyInto%28S%29)拷貝進另一個可變集合;
* 用[`immutableCopy()`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.SetView.html#immutableCopy%28%29)對自己做不可變拷貝。
| **方法** |
|:--- |
| [`union(Set, Set)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#union%28java.util.Set, java.util.Set%29) |
| [`intersection(Set, Set)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#intersection%28java.util.Set, java.util.Set%29) |
| [`difference(Set, Set)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#difference%28java.util.Set, java.util.Set%29) |
| [`symmetricDifference(Set, ? Set)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#symmetricDifference%28java.util.Set, java.util.Set%29) |
使用范例:
```
Set<String> wordsWithPrimeLength = ImmutableSet.of("one", "two", "three", "six", "seven", "eight");
Set<String> primes = ImmutableSet.of("two", "three", "five", "seven");
SetView<String> intersection = Sets.intersection(primes,wordsWithPrimeLength);
// intersection包含"two", "three", "seven"
return intersection.immutableCopy();//可以使用交集,但不可變拷貝的讀取效率更高
```
### 其他Set工具方法
| **方法** | **描述** | **另請參見** |
|:--- |:--- |:--- |
| [`cartesianProduct(List<Set>)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#cartesianProduct%28java.util.List%29) | 返回所有集合的笛卡兒積 | [`cartesianProduct(Set...)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#cartesianProduct%28java.util.Set...%29) |
| [`powerSet(Set)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#powerSet%28java.util.Set%29) | 返回給定集合的所有子集 |
```
Set<String> animals = ImmutableSet.of("gerbil", "hamster");
Set<String> fruits = ImmutableSet.of("apple", "orange", "banana");
Set<List<String>> product = Sets.cartesianProduct(animals, fruits);
// {{"gerbil", "apple"}, {"gerbil", "orange"}, {"gerbil", "banana"},
// ?{"hamster", "apple"}, {"hamster", "orange"}, {"hamster", "banana"}}
Set<Set<String>> animalSets = Sets.powerSet(animals);
// {{}, {"gerbil"}, {"hamster"}, {"gerbil", "hamster"}}
```
### 靜態工廠方法
Sets提供如下靜態工廠方法:
| **具體實現類型** | **工廠方法** |
|:--- |:--- |
| HashSet | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newHashSet%28%29), [with elements](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newHashSet%28E...%29), [from `Iterable`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newHashSet%28java.lang.Iterable%29), [with expected size](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newHashSetWithExpectedSize%28int%29), [from `Iterator`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newHashSet%28java.util.Iterator%29) |
| LinkedHashSet | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newLinkedHashSet%28%29), [from `Iterable`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newLinkedHashSet%28java.lang.Iterable%29), [with expected size](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newLinkedHashSetWithExpectedSize%28int%29) |
| TreeSet | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newTreeSet%28%29), [with `Comparator`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newTreeSet%28java.util.Comparator%29), [from `Iterable`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Sets.html#newTreeSet%28java.lang.Iterable%29) |
## Maps
[`Maps`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html)類有若干值得單獨說明的、很酷的方法。
### uniqueIndex
[`Maps.uniqueIndex(Iterable,Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#uniqueIndex%28java.lang.Iterable, com.google.common.base.Function%29)通常針對的場景是:有一組對象,它們在某個屬性上分別有獨一無二的值,而我們希望能夠按照這個屬性值查找對象——_譯者注:這個方法返回一個__Map,鍵為Function返回的屬性值,值為Iterable中相應的元素,因此我們可以反復用這個Map進行查找操作。_
比方說,我們有一堆字符串,這些字符串的長度都是獨一無二的,而我們希望能夠按照特定長度查找字符串:
```
ImmutableMap<Integer, String> stringsByIndex = Maps.uniqueIndex(strings,
new Function<String, Integer> () {
public Integer apply(String string) {
return string.length();
}
});
```
如果索引值不是獨一無二的,請參見下面的Multimaps.index方法。
### difference
[`Maps.difference(Map, Map)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#difference%28java.util.Map, java.util.Map%29)用來比較兩個Map以獲取所有不同點。該方法返回MapDifference對象,把不同點的維恩圖分解為:
| [`entriesInCommon()`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/MapDifference.html#entriesInCommon%28%29) | 兩個Map中都有的映射項,包括匹配的鍵與值 |
|:--- |:--- |
| [`entriesDiffering()`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/MapDifference.html#entriesDiffering%28%29) | 鍵相同但是值不同值映射項。返回的Map的值類型為[`MapDifference.ValueDifference`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/MapDifference.ValueDifference.html),以表示左右兩個不同的值 |
| [`entriesOnlyOnLeft()`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/MapDifference.html#entriesOnlyOnLeft%28%29) | 鍵只存在于左邊Map的映射項 |
| [`entriesOnlyOnRight()`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/MapDifference.html#entriesOnlyOnRight%28%29) | 鍵只存在于右邊Map的映射項 |
```
Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
MapDifference<String, Integer> diff = Maps.difference(left, right);
diff.entriesInCommon(); // {"b" => 2}
diff.entriesInCommon(); // {"b" => 2}
diff.entriesOnlyOnLeft(); // {"a" => 1}
diff.entriesOnlyOnRight(); // {"d" => 5}
```
### 處理BiMap的工具方法
Guava中處理BiMap的工具方法在Maps類中,因為BiMap也是一種Map實現。
| **BiMap****工具方法** | **相應的****Map****工具方法** |
|:--- |:--- |
| [`synchronizedBiMap(BiMap)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…common/collect/Maps.html#synchronizedBiMap%28com.google.common.collect.BiMap%29) | Collections.synchronizedMap(Map) |
| [`unmodifiableBiMap(BiMap)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…common/collect/Maps.html#unmodifiableBiMap%28com.google.common.collect.BiMap%29) | Collections.unmodifiableMap(Map) |
### 靜態工廠方法
Maps提供如下靜態工廠方法:
| **具體實現類型** | **工廠方法** |
|:--- |:--- |
| HashMap | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newHashMap%28%29), [from `Map`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newHashMap%28java.util.Map%29), [with expected size](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newHashMapWithExpectedSize%28int%29) |
| LinkedHashMap | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newLinkedHashMap%28%29), [from `Map`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newLinkedHashMap%28java.util.Map%29) |
| TreeMap | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newTreeMap%28%29), [from `Comparator`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newTreeMap%28java.util.Comparator%29), [from `SortedMap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newTreeMap%28java.util.SortedMap%29) |
| EnumMap | [from `Class`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newEnumMap%28java.lang.Class%29), [from `Map`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newEnumMap%28java.util.Map%29) |
| ConcurrentMap:支持所有操作 | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newConcurrentMap%28%29) |
| IdentityHashMap | [basic](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#newIdentityHashMap%28%29) |
## Multisets
標準的Collection操作會忽略Multiset重復元素的個數,而只關心元素是否存在于Multiset中,如containsAll方法。為此,[`Multisets`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multisets.html)提供了若干方法,以顧及Multiset元素的重復性:
| **方法** | **說明** | **和****Collection****方法的區別** |
|:--- |:--- |:--- |
| [`containsOccurrences(Multiset ? sup, Multiset sub)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…lect/Multisets.html#containsOccurrences%28com.google.common.collect.Multiset, com.google.common.collect.Multiset%29) | 對任意o,如果sub.count(o)<=super.count(o),返回true | Collection.containsAll忽略個數,而只關心sub的元素是否都在super中 |
| [`removeOccurrences(Multiset ? removeFrom, Multiset toRemove)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…ollect/Multisets.html#removeOccurrences%28com.google.common.collect.Multiset, com.google.common.collect.Multiset%29) | 對toRemove中的重復元素,僅在removeFrom中刪除相同個數。 | Collection.removeAll移除所有出現在toRemove的元素 |
| [`retainOccurrences(Multiset ? removeFrom, Multiset toRetain)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…ollect/Multisets.html#retainOccurrences%28com.google.common.collect.Multiset, com.google.common.collect.Multiset%29) | 修改removeFrom,以保證任意o都符合removeFrom.count(o)<=toRetain.count(o) | Collection.retainAll保留所有出現在toRetain的元素 |
| [`intersection(Multiset, ? Multiset)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…mon/collect/Multisets.html#intersection%28com.google.common.collect.Multiset, com.google.common.collect.Multiset%29) | 返回兩個multiset的交集; | 沒有類似方法 |
```
Multiset<String> multiset1 = HashMultiset.create();
multiset1.add("a", 2);
Multiset<String> multiset2 = HashMultiset.create();
multiset2.add("a", 5);
multiset1.containsAll(multiset2); //返回true;因為包含了所有不重復元素,
//雖然multiset1實際上包含2個"a",而multiset2包含5個"a"
Multisets.containsOccurrences(multiset1, multiset2); // returns false
multiset2.removeOccurrences(multiset1); // multiset2 現在包含3個"a"
multiset2.removeAll(multiset1);//multiset2移除所有"a",雖然multiset1只有2個"a"
multiset2.isEmpty(); // returns true
```
Multisets中的其他工具方法還包括:
| [`copyHighestCountFirst(Multiset)`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/co…ct/Multisets.html#copyHighestCountFirst%28com.google.common.collect.Multiset%29) | 返回Multiset的不可變拷貝,并將元素按重復出現的次數做降序排列 |
|:--- |:--- |
| [`unmodifiableMultiset(Multiset)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…ect/Multisets.html#unmodifiableMultiset%28com.google.common.collect.Multiset%29) | 返回Multiset的只讀視圖 |
| [`unmodifiableSortedMultiset(SortedMultiset)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…s.html#unmodifiableSortedMultiset%28com.google.common.collect.SortedMultiset%29) | 返回SortedMultiset的只讀視圖 |
```
Multiset<String> multiset = HashMultiset.create();
multiset.add("a", 3);
multiset.add("b", 5);
multiset.add("c", 1);
ImmutableMultiset highestCountFirst = Multisets.copyHighestCountFirst(multiset);
//highestCountFirst,包括它的entrySet和elementSet,按{"b", "a", "c"}排列元素
```
## Multimaps
[`Multimaps`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimaps.html)提供了若干值得單獨說明的通用工具方法
### index
作為Maps.uniqueIndex的兄弟方法,[`Multimaps.index(Iterable, Function)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimaps.html#index%28java.lang.Iterable, com.google.common.base.Function%29)通常針對的場景是:有一組對象,它們有共同的特定屬性,我們希望按照這個屬性的值查詢對象,但屬性值不一定是獨一無二的。
比方說,我們想把字符串按長度分組。
```
ImmutableSet digits = ImmutableSet.of("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine");
Function<String, Integer> lengthFunction = new Function<String, Integer>() {
public Integer apply(String string) {
return string.length();
}
};
ImmutableListMultimap<Integer, String> digitsByLength= Multimaps.index(digits, lengthFunction);
/*
* ?digitsByLength maps:
* ?3 => {"one", "two", "six"}
* ?4 => {"zero", "four", "five", "nine"}
* ?5 => {"three", "seven", "eight"}
*/
```
### invertFrom
鑒于Multimap可以把多個鍵映射到同一個值(_譯者注:實際上這是任何__map都有的特性_),也可以把一個鍵映射到多個值,反轉Multimap也會很有用。Guava 提供了[`invertFrom(Multimap toInvert,
Multimap dest)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…ommon/collect/Multimaps.html#invertFrom(com.google.common.collect.Multimap, M))做這個操作,并且你可以自由選擇反轉后的Multimap實現。
注:如果你使用的是ImmutableMultimap,考慮改用[`ImmutableMultimap.inverse()`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/ImmutableMultimap.html#inverse%28%29)做反轉。
```
ArrayListMultimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.putAll("b", Ints.asList(2, 4, 6));
multimap.putAll("a", Ints.asList(4, 2, 1));
multimap.putAll("c", Ints.asList(2, 5, 3));
TreeMultimap<Integer, String> inverse = Multimaps.invertFrom(multimap, TreeMultimap<String, Integer>.create());
//注意我們選擇的實現,因為選了TreeMultimap,得到的反轉結果是有序的
/*
* inverse maps:
* ?1 => {"a"}
* ?2 => {"a", "b", "c"}
* ?3 => {"c"}
* ?4 => {"a", "b"}
* ?5 => {"c"}
* ?6 => {"b"}
*/
```
### forMap
想在Map對象上使用Multimap的方法嗎?[`forMap(Map)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimaps.html#forMap%28java.util.Map%29)把Map包裝成SetMultimap。這個方法特別有用,例如,與Multimaps.invertFrom結合使用,可以把多對一的Map反轉為一對多的Multimap。
```
Map<String, Integer> map = ImmutableMap.of("a", 1, "b", 1, "c", 2);
SetMultimap<String, Integer> multimap = Multimaps.forMap(map);
// multimap:["a" => {1}, "b" => {1}, "c" => {2}]
Multimap<Integer, String> inverse = Multimaps.invertFrom(multimap, HashMultimap<Integer, String>.create());
// inverse:[1 => {"a","b"}, 2 => {"c"}]
```
### 包裝器
Multimaps提供了傳統的包裝方法,以及讓你選擇Map和Collection類型以自定義Multimap實現的工具方法。
| 只讀包裝 | [`Multimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…ect/Multimaps.html#unmodifiableMultimap%28com.google.common.collect.Multimap%29) | [`ListMultimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…imaps.html#unmodifiableListMultimap%28com.google.common.collect.ListMultimap%29) | [`SetMultimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…ltimaps.html#unmodifiableSetMultimap%28com.google.common.collect.SetMultimap%29) | [`SortedSetMultimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…#unmodifiableSortedSetMultimap%28com.google.common.collect.SortedSetMultimap%29) |
|:--- |:--- |:--- |:--- |:--- |
| 同步包裝 | [`Multimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…ect/Multimaps.html#synchronizedMultimap%28com.google.common.collect.Multimap%29) | [`ListMultimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…imaps.html#synchronizedListMultimap%28com.google.common.collect.ListMultimap%29) | [`SetMultimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…ltimaps.html#synchronizedSetMultimap%28com.google.common.collect.SetMultimap%29) | [`SortedSetMultimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…#synchronizedSortedSetMultimap%28com.google.common.collect.SortedSetMultimap%29) |
| 自定義實現 | [`Multimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimaps.html#newMultimap%28java.util.Map, com.google.common.base.Supplier%29) | [`ListMultimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimaps.html#newListMultimap%28java.util.Map, com.google.common.base.Supplier%29) | [`SetMultimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimaps.html#newSetMultimap%28java.util.Map, com.google.common.base.Supplier%29) | [`SortedSetMultimap`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Multimaps.html#newSortedSetMultimap%28java.util.Map, com.google.common.base.Supplier%29) |
自定義Multimap的方法允許你指定Multimap中的特定實現。但要注意的是:
* Multimap假設對Map和Supplier產生的集合對象有完全所有權。這些自定義對象應避免手動更新,并且在提供給Multimap時應該是空的,此外還不應該使用軟引用、弱引用或虛引用。
* 無法保證修改了Multimap以后,底層Map的內容是什么樣的。
* 即使Map和Supplier產生的集合都是線程安全的,它們組成的Multimap也不能保證并發操作的線程安全性。并發讀操作是工作正常的,但需要保證并發讀寫的話,請考慮用同步包裝器解決。
* 只有當Map、Supplier、Supplier產生的集合對象、以及Multimap存放的鍵值類型都是可序列化的,Multimap才是可序列化的。
* Multimap.get(key)返回的集合對象和Supplier返回的集合對象并不是同一類型。但如果Supplier返回的是隨機訪問集合,那么Multimap.get(key)返回的集合也是可隨機訪問的。
請注意,用來自定義Multimap的方法需要一個Supplier參數,以創建嶄新的集合。下面有個實現ListMultimap的例子——用TreeMap做映射,而每個鍵對應的多個值用LinkedList存儲。
```
ListMultimap<String, Integer> myMultimap = Multimaps.newListMultimap(
Maps.<String, Collection>newTreeMap(),
new Supplier<LinkedList>() {
public LinkedList get() {
return Lists.newLinkedList();
}
});
```
## Tables
[`Tables`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Tables.html)類提供了若干稱手的工具方法。
### 自定義Table
堪比Multimaps.newXXXMultimap(Map, Supplier)工具方法,[`Tables.newCustomTable(Map, Supplier<Map>)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Tables.html#newCustomTable%28java.util.Map, com.google.common.base.Supplier%29)允許你指定Table用什么樣的map實現行和列。
```
// 使用LinkedHashMaps替代HashMaps
Table<String, Character, Integer> table = Tables.newCustomTable(
Maps.<String, Map<Character, Integer>>newLinkedHashMap(),
new Supplier<Map<Character, Integer>> () {
public Map<Character, Integer> get() {
return Maps.newLinkedHashMap();
}
});
```
### transpose
[`transpose(Table<R, C, V>)`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Tables.html#transpose%28com.google.common.collect.Table%29)方法允許你把Table<C, R, V>轉置成Table<R, C, V>。例如,如果你在用Table構建加權有向圖,這個方法就可以把有向圖反轉。
### 包裝器
還有很多你熟悉和喜歡的Table包裝類。然而,在大多數情況下還請使用[`ImmutableTable`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/ImmutableTable.html)
| Unmodifiable |
|:--- |
| [`Table`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…mmon/collect/Tables.html#unmodifiableTable%28com.google.common.collect.Table%29) |
| [`RowSortedTable`](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/…s.html#unmodifiableRowSortedTable%28com.google.common.collect.RowSortedTable%29) |
- Spring 中文文檔 3.1
- 第一部分 Spring framework 概述
- 第 1 章 Spring Framework 介紹
- 1.1 依賴注入和控制反轉
- 1.2 模塊
- 1.3 使用方案
- 第二部分 Spring 3 的新特性
- 第 2 章 Spring 3.0 的新特性和增強
- 2.1 Java 5
- 2.2 改進的文檔
- 2.3 新的文章和教程
- 2.4 新的模塊組織方式和系統構建方式
- 2.5 新特性概述
- 第 3 章 Spring 3.1 的新特性和增強
- 3.1 新特性概述
- 第三部分 核心技術
- 第 4 章 IoC 容器
- 4.1 Spring IoC 容器和 bean 的介紹
- 4.2 容器概述
- 4.3 Bean 概述
- 4.4 依賴
- 4.5 Bean 的范圍
- 4.6 自定義 bean 的性質
- 4.7 Bean 定義的繼承
- 4.8 容器擴展點
- 4.9 基于注解的容器配置
- 4.10 類路徑掃描和管理的組件
- 4.11 使用 JSR 330 標準注解
- 4.12 基于 Java 的容器配置
- Hibernate 中文文檔 3.2
- 前言
- 1. 翻譯說明
- 2. 版權聲明
- 第 1 章 Hibernate入門
- 1.1. 前言
- 1.2. 第一部分 - 第一個Hibernate應用程序
- 1.2.1. 第一個class
- 1.2.2. 映射文件
- 1.2.3. Hibernate配置
- 1.2.4. 用Ant構建
- 1.2.5. 啟動和輔助類
- 1.2.6. 加載并存儲對象
- 1.3. 第二部分 - 關聯映射
- 1.3.1. 映射Person類
- 1.3.2. 單向Set-based的關聯
- 1.3.3. 使關聯工作
- 1.3.4. 值類型的集合
- 1.3.5. 雙向關聯
- 1.3.6. 使雙向連起來
- 1.4. 第三部分 - EventManager web應用程序
- 1.4.1. 編寫基本的servlet
- 1.4.2. 處理與渲染
- 1.4.3. 部署與測試
- 1.5. 總結
- 第 2 章 體系結構(Architecture)
- 2.1. 概況(Overview)
- 2.2. 實例狀態
- 2.3. JMX整合
- 2.4. 對JCA的支持
- 2.5. 上下文相關的(Contextual)Session
- 第 3 章 配置
- 3.1. 可編程的配置方式
- 3.2. 獲得SessionFactory
- 3.3. JDBC連接
- 3.4. 可選的配置屬性
- 3.4.1. SQL方言
- 3.4.2. 外連接抓取(Outer Join Fetching)
- 3.4.3. 二進制流 (Binary Streams)
- 3.4.4. 二級緩存與查詢緩存
- 3.4.5. 查詢語言中的替換
- 3.4.6. Hibernate的統計(statistics)機制
- 3.5. 日志
- 3.6. 實現NamingStrategy
- 3.7. XML配置文件
- 3.8. J2EE應用程序服務器的集成
- 3.8.1. 事務策略配置
- 3.8.2. JNDI綁定的SessionFactory
- 3.8.3. 在JTA環境下使用Current Session context (當前session上下文)管理
- 3.8.4. JMX部署
- 第 4 章 持久化類(Persistent Classes)
- 4.1. 一個簡單的POJO例子
- 4.1.1. 實現一個默認的(即無參數的)構造方法(constructor)
- 4.1.2. 提供一個標識屬性(identifier property)(可選)
- 4.1.3. 使用非final的類 (可選)
- 4.1.4. 為持久化字段聲明訪問器(accessors)和是否可變的標志(mutators)(可選)
- 4.2. 實現繼承(Inheritance)
- 4.3. 實現equals()和hashCode()
- 4.4. 動態模型(Dynamic models)
- 4.5. 元組片斷映射(Tuplizers)
- 第 5 章 對象/關系數據庫映射基礎(Basic O/R Mapping)
- 5.1. 映射定義(Mapping declaration)
- 5.1.1. Doctype
- 5.1.1.1. EntityResolver
- 5.1.2. hibernate-mapping
- 5.1.3. class
- 5.1.4. id
- 5.1.4.1. Generator
- 5.1.4.2. 高/低位算法(Hi/Lo Algorithm)
- 5.1.4.3. UUID算法(UUID Algorithm )
- 5.1.4.4. 標識字段和序列(Identity columns and Sequences)
- 5.1.4.5. 程序分配的標識符(Assigned Identifiers)
- 5.1.4.6. 觸發器實現的主鍵生成器(Primary keys assigned by triggers)
- 5.1.5. composite-id
- 5.1.6. 鑒別器(discriminator)
- 5.1.7. 版本(version)(可選)
- 5.1.8. timestamp (可選)
- 5.1.9. property
- 5.1.10. 多對一(many-to-one)
- 5.1.11. 一對一
- 5.1.12. 自然ID(natural-id)
- 5.1.13. 組件(component), 動態組件(dynamic-component)
- 5.1.14. properties
- 5.1.15. 子類(subclass)
- 5.1.16. 連接的子類(joined-subclass)
- 5.1.17. 聯合子類(union-subclass)
- 5.1.18. 連接(join)
- 5.1.19. 鍵(key)
- 5.1.20. 字段和規則元素(column and formula elements)
- 5.1.21. 引用(import)
- 5.1.22. any
- 5.2. Hibernate 的類型
- 5.2.1. 實體(Entities)和值(values)
- 5.2.2. 基本值類型
- 5.2.3. 自定義值類型
- 5.3. 多次映射同一個類
- 5.4. SQL中引號包圍的標識符
- 5.5. 其他元數據(Metadata)
- 5.5.1. 使用 XDoclet 標記
- 5.5.2. 使用 JDK 5.0 的注解(Annotation)
- 5.6. 數據庫生成屬性(Generated Properties)
- 5.7. 輔助數據庫對象(Auxiliary Database Objects)
- 第 6 章 集合類(Collections)映射
- 6.1. 持久化集合類(Persistent collections)
- 6.2. 集合映射( Collection mappings )
- 6.2.1. 集合外鍵(Collection foreign keys)
- 6.2.2. 集合元素(Collection elements)
- 6.2.3. 索引集合類(Indexed collections)
- 6.2.4. 值集合于多對多關聯(Collections of values and many-to-many associations)
- 6.2.5. 一對多關聯(One-to-many Associations)
- 6.3. 高級集合映射(Advanced collection mappings)
- 6.3.1. 有序集合(Sorted collections)
- 6.3.2. 雙向關聯(Bidirectional associations)
- 6.3.3. 雙向關聯,涉及有序集合類
- 6.3.4. 三重關聯(Ternary associations)
- 6.3.5. 使用&amp;lt;idbag&amp;gt;
- 6.4. 集合例子(Collection example)
- 第 7 章 關聯關系映射
- 7.1. 介紹
- 7.2. 單向關聯(Unidirectional associations)
- 7.2.1. 多對一(many to one)
- 7.2.2. 一對一(one to one)
- 7.2.3. 一對多(one to many)
- 7.3. 使用連接表的單向關聯(Unidirectional associations with join tables)
- 7.3.1. 一對多(one to many)
- 7.3.2. 多對一(many to one)
- 7.3.3. 一對一(one to one)
- 7.3.4. 多對多(many to many)
- 7.4. 雙向關聯(Bidirectional associations)
- 7.4.1. 一對多(one to many) / 多對一(many to one)
- 7.4.2. 一對一(one to one)
- 7.5. 使用連接表的雙向關聯(Bidirectional associations with join tables)
- 7.5.1. 一對多(one to many) /多對一( many to one)
- 7.5.2. 一對一(one to one)
- 7.5.3. 多對多(many to many)
- 7.6. 更復雜的關聯映射
- 第 8 章 組件(Component)映射
- 8.1. 依賴對象(Dependent objects)
- 8.2. 在集合中出現的依賴對象 (Collections of dependent objects)
- 8.3. 組件作為Map的索引(Components as Map indices )
- 8.4. 組件作為聯合標識符(Components as composite identifiers)
- 8.5. 動態組件 (Dynamic components)
- 第 9 章 繼承映射(Inheritance Mappings)
- 9.1. 三種策略
- 9.1.1. 每個類分層結構一張表(Table per class hierarchy)
- 9.1.2. 每個子類一張表(Table per subclass)
- 9.1.3. 每個子類一張表(Table per subclass),使用辨別標志(Discriminator)
- 9.1.4. 混合使用“每個類分層結構一張表”和“每個子類一張表”
- 9.1.5. 每個具體類一張表(Table per concrete class)
- 9.1.6. Table per concrete class, using implicit polymorphism
- 9.1.7. 隱式多態和其他繼承映射混合使用
- 9.2. 限制
- 第 10 章 與對象共事
- 10.1. Hibernate對象狀態(object states)
- 10.2. 使對象持久化
- 10.3. 裝載對象
- 10.4. 查詢
- 10.4.1. 執行查詢
- 10.4.1.1. 迭代式獲取結果(Iterating results)
- 10.4.1.2. 返回元組(tuples)的查詢
- 10.4.1.3. 標量(Scalar)結果
- 10.4.1.4. 綁定參數
- 10.4.1.5. 分頁
- 10.4.1.6. 可滾動遍歷(Scrollable iteration)
- 10.4.1.7. 外置命名查詢(Externalizing named queries)
- 10.4.2. 過濾集合
- 10.4.3. 條件查詢(Criteria queries)
- 10.4.4. 使用原生SQL的查詢
- 10.5. 修改持久對象
- 10.6. 修改脫管(Detached)對象
- 10.7. 自動狀態檢測
- 10.8. 刪除持久對象
- 10.9. 在兩個不同數據庫間復制對象
- 10.10. Session刷出(flush)
- 10.11. 傳播性持久化(transitive persistence)
- 10.12. 使用元數據
- 第 11 章 事務和并發
- 11.1. Session和事務范圍(transaction scope)
- 11.1.1. 操作單元(Unit of work)
- 11.1.2. 長對話
- 11.1.3. 關注對象標識(Considering object identity)
- 11.1.4. 常見問題
- 11.2. 數據庫事務聲明
- 11.2.1. 非托管環境
- 11.2.2. 使用JTA
- 11.2.3. 異常處理
- 11.2.4. 事務超時
- 11.3. 樂觀并發控制(Optimistic concurrency control)
- 11.3.1. 應用程序級別的版本檢查(Application version checking)
- 11.3.2. 擴展周期的session和自動版本化
- 11.3.3. 脫管對象(deatched object)和自動版本化
- 11.3.4. 定制自動版本化行為
- 11.4. 悲觀鎖定(Pessimistic Locking)
- 11.5. 連接釋放模式(Connection Release Modes)
- 第 12 章 攔截器與事件(Interceptors and events)
- 12.1. 攔截器(Interceptors)
- 12.2. 事件系統(Event system)
- 12.3. Hibernate的聲明式安全機制
- 第 13 章 批量處理(Batch processing)
- 13.1. 批量插入(Batch inserts)
- 13.2. 批量更新(Batch updates)
- 13.3. StatelessSession (無狀態session)接口
- 13.4. DML(數據操作語言)風格的操作(DML-style operations)
- 第 14 章 HQL: Hibernate查詢語言
- 14.1. 大小寫敏感性問題
- 14.2. from子句
- 14.3. 關聯(Association)與連接(Join)
- 14.4. join 語法的形式
- 14.5. select子句
- 14.6. 聚集函數
- 14.7. 多態查詢
- 14.8. where子句
- 14.9. 表達式
- 14.10. order by子句
- 14.11. group by子句
- 14.12. 子查詢
- 14.13. HQL示例
- 14.14. 批量的UPDATE和DELETE
- 14.15. 小技巧 & 小竅門
- 第 15 章 條件查詢(Criteria Queries)
- 15.1. 創建一個Criteria 實例
- 15.2. 限制結果集內容
- 15.3. 結果集排序
- 15.4. 關聯
- 15.5. 動態關聯抓取
- 15.6. 查詢示例
- 15.7. 投影(Projections)、聚合(aggregation)和分組(grouping)
- 15.8. 離線(detached)查詢和子查詢
- 15.9. 根據自然標識查詢(Queries by natural identifier)
- 第 16 章 Native SQL查詢
- 16.1. 使用SQLQuery
- 16.1.1. 標量查詢(Scalar queries)
- 16.1.2. 實體查詢(Entity queries)
- 16.1.3. 處理關聯和集合類(Handling associations and collections)
- 16.1.4. 返回多個實體(Returning multiple entities)
- 16.1.4.1. 別名和屬性引用(Alias and property references)
- 16.1.5. 返回非受管實體(Returning non-managed entities)
- 16.1.6. 處理繼承(Handling inheritance)
- 16.1.7. 參數(Parameters)
- 16.2. 命名SQL查詢
- 16.2.1. 使用return-property來明確地指定字段/別名
- 16.2.2. 使用存儲過程來查詢
- 16.2.2.1. 使用存儲過程的規則和限制
- 16.3. 定制SQL用來create,update和delete
- 16.4. 定制裝載SQL
- 第 17 章 過濾數據
- 17.1. Hibernate 過濾器(filters)
- 第 18 章 XML映射
- 18.1. 用XML數據進行工作
- 18.1.1. 指定同時映射XML和類
- 18.1.2. 只定義XML映射
- 18.2. XML映射元數據
- 18.3. 操作XML數據
- 第 19 章 提升性能
- 19.1. 抓取策略(Fetching strategies)
- 19.1.1. 操作延遲加載的關聯
- 19.1.2. 調整抓取策略(Tuning fetch strategies)
- 19.1.3. 單端關聯代理(Single-ended association proxies)
- 19.1.4. 實例化集合和代理(Initializing collections and proxies)
- 19.1.5. 使用批量抓取(Using batch fetching)
- 19.1.6. 使用子查詢抓取(Using subselect fetching)
- 19.1.7. 使用延遲屬性抓取(Using lazy property fetching)
- 19.2. 二級緩存(The Second Level Cache)
- 19.2.1. 緩存映射(Cache mappings)
- 19.2.2. 策略:只讀緩存(Strategy: read only)
- 19.2.3. 策略:讀/寫緩存(Strategy: read/write)
- 19.2.4. 策略:非嚴格讀/寫緩存(Strategy: nonstrict read/write)
- 19.2.5. 策略:事務緩存(transactional)
- 19.3. 管理緩存(Managing the caches)
- 19.4. 查詢緩存(The Query Cache)
- 19.5. 理解集合性能(Understanding Collection performance)
- 19.5.1. 分類(Taxonomy)
- 19.5.2. Lists, maps 和sets用于更新效率最高
- 19.5.3. Bag和list是反向集合類中效率最高的
- 19.5.4. 一次性刪除(One shot delete)
- 19.6. 監測性能(Monitoring performance)
- 19.6.1. 監測SessionFactory
- 19.6.2. 數據記錄(Metrics)
- 第 20 章 工具箱指南
- 20.1. Schema自動生成(Automatic schema generation)
- 20.1.1. 對schema定制化(Customizing the schema)
- 20.1.2. 運行該工具
- 20.1.3. 屬性(Properties)
- 20.1.4. 使用Ant(Using Ant)
- 20.1.5. 對schema的增量更新(Incremental schema updates)
- 20.1.6. 用Ant來增量更新schema(Using Ant for incremental schema updates)
- 20.1.7. Schema 校驗
- 20.1.8. 使用Ant進行schema校驗
- 第 21 章 示例:父子關系(Parent Child Relationships)
- 21.1. 關于collections需要注意的一點
- 21.2. 雙向的一對多關系(Bidirectional one-to-many)
- 21.3. 級聯生命周期(Cascading lifecycle)
- 21.4. 級聯與未保存值(Cascades and unsaved-value)
- 21.5. 結論
- 第 22 章 示例:Weblog 應用程序
- 22.1. 持久化類
- 22.2. Hibernate 映射
- 22.3. Hibernate 代碼
- 第 23 章 示例:復雜映射實例
- 23.1. Employer(雇主)/Employee(雇員)
- 23.2. Author(作家)/Work(作品)
- 23.3. Customer(客戶)/Order(訂單)/Product(產品)
- 23.4. 雜例
- 23.4.1. "Typed" one-to-one association
- 23.4.2. Composite key example
- 23.4.3. 共有組合鍵屬性的多對多(Many-to-many with shared composite key attribute)
- 23.4.4. Content based discrimination
- 23.4.5. Associations on alternate keys
- 第 24 章 最佳實踐(Best Practices)
- HttpClient 教程
- 前言
- 第一章 基礎
- 第二章 連接管理
- 第三章 HTTP狀態管理
- 第四章 HTTP認證
- 第五章 HTTP客戶端服務
- 第六章 高級主題
- Mybatis 中文文檔 3.4
- 參考文檔
- 簡介
- 入門
- XML 映射配置文件
- Mapper XML 文件
- 動態 SQL
- Java API
- SQL語句構建器類
- Logging
- 項目文檔
- 項目總體信息
- 訪問
- 提醒方法
- 項目依賴
- Dependency Information
- Overview
- 問題跟蹤
- 項目授權
- 項目郵件列表
- Project Plugin Management
- Project Build Plugins
- Project Report Plugins
- 團隊
- Web訪問
- 匿名訪問
- 開發者訪問
- 通過防火墻訪問
- 項目概要
- 生成報表
- MyBatis Generator 用戶手冊
- MyBatis Generator介紹
- MyBatis Generator新增功能
- MyBatis Generator 快速入門指南
- 運行 MyBatis Generator
- 從命令行運行 MyBatis Generator
- 使用Ant運行 MyBatis Generator
- 通過Maven運行 MyBatis Generator
- 使用Java運行 MyBatis Generator
- 運行 MyBatis Generator 后的任務
- Migrating from Ibator
- Migrating from Abator
- MyBatis Generator XML 配置參考
- &lt;classPathEntry&gt; 元素
- &lt;columnOverride&gt; 元素
- &lt;columnRenamingRule&gt; 元素
- &lt;commentGenerator&gt; 元素
- &lt;context&gt; 元素
- &lt;generatedKey&gt; 元素
- &lt;generatorConfiguration&gt; 元素
- &lt;ignoreColumn&gt; 元素
- &lt;javaClientGenerator&gt; 元素
- The &lt;javaModelGenerator&gt; Element
- The &lt;javaTypeResolver&gt; Element
- &lt;jdbcConnection&gt; 元素
- &lt;plugin&gt; 元素
- &lt;properties&gt; 元素
- &lt;property&gt; 元素
- &lt;sqlMapGenerator&gt; 元素
- &lt;table&gt; 元素
- 使用生成的對象
- JAVA實體對象
- SQL映射文件
- Java客戶端對象
- Example類使用說明
- 擴展Example類
- 使用注意事項
- DB2 使用注意事項
- MySql 使用注意事項
- Oracle 使用注意事項
- PostgreSQL 使用注意事項
- 參考資料
- 從源碼構建
- 擴展MyBatis Generator
- 開發插件
- 日志信息
- 提供的插件
- 設計理念
- Velocity 中文文檔
- 1. 關于
- 2. 什么是Velocity?
- 3. Velocity 可以做什么?
- 3.1. Mud Store 示例
- 4. Velocity模板語言(VTL): 介紹
- 5. Hello Velocity World!
- 6. 注釋
- 7. 引用
- 7.1. 變量Variables
- 7.2. 屬性
- 7.3. 方法
- 8. 形式引用符Formal Reference Notation
- 9. 安靜引用符Quiet Reference Notation
- 11. Case Substitution
- 12. 指令
- 12.1. #set
- 12.2. 字面字符串
- 12.3. 條件
- 12.3.1 If / ElseIf / Else
- 12.3.2 關系和邏輯操作符
- 12.4. 循環
- 12.4.1. Foreach 循環
- 12.5. 包含
- 12.6. 解析
- 12.7. 停止
- 12.10. 宏
- 12.10.1. Velocimacro 參數
- 12.10.2. Velocimacro 屬性
- 12.10.3. Velocimacro Trivia
- 13. Getting literal
- 13.1. 貨幣字符
- 13.2. 轉義 有效的 VTL 指令
- 13.3. 轉義 無效的 VTL 指令
- 14. VTL 格式化問題
- 15. 其它特征和雜項
- 15.1. 數學特征
- 15.2. 范圍操作符
- 15.3. 進階:轉義和!
- 15.4. Velocimacro 雜記
- 15.5. 字符串聯
- 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-原生類型
- 8-區間
- 9-I/O
- 10-散列
- 11-事件總線
- 12-數學運算
- 13-反射
- JFreeChart 開發者指南
- 1 簡介
- 1.1 什么是JFreeChart
- 1.2 使用文檔
- 1.3 感謝
- 1.4 建議
- 2 圖表實例
- 2.1 介紹
- 2.2 餅圖(Pie Charts)
- 2.3 直方條形圖(Bar Charts)
- 2.4 折線圖(Line Charts)
- 2.5 XY(散點圖)
- 2.6 時序圖
- 2.7 柱狀圖
- 2.8 面積圖
- 2.9 差異圖
- 2.10 梯形圖
- 2.11 甘特圖
- 2.12 多軸圖
- 2.13 復合/覆蓋圖
- 2.14 開發遠景
- 3 下載和安裝JFreeChart 1.0.6
- 3.1 簡介
- 3.2 下載
- 3.3 解包
- 3.4 運行演示實例
- 3.5 編譯源代碼
- 3.6 產生javadoc文檔
- 4 使用JFreeChart1.0.6
- 4.1 概述
- 4.2 創建第一個圖表
- 5 餅圖(Pie Charts)
- 5.1 簡介
- 5.2 創建一個簡單的餅圖(Pie Charts)
- 5.3 片區顏色
- 5.4 片區外廓
- 5.5 空置、零值和負值
- 5.6 片區和圖例標簽
- 5.7 “取出”某個片區
- 5.8 3D餅圖
- 5.9 多餅圖
- 5.10 實例講解
- 6 直方條形圖(Bar Charts)
- 6.1 簡介
- 6.2 創建一個直方條形圖
- 6.3 ChartFactory類
- 6.4 直方條形圖的簡單定制
- 6.5 定制外觀
- 6.6 示例代碼解讀
- 7 折線圖
- 7.1 簡介
- 7.2 使用categoryDataset數據集創建折線圖
- 7.3 使用XYDataset數據集創建折線圖
- 8 時序圖
- 8.1 簡介
- 8.2 創建時序圖
- 9 定制圖表(Customising Charts)
- 9.1 簡介
- 9.2 圖表屬性
- 9.3 圖區屬性
- 9.4 軸屬性
- 9.5 心得體會
- 10 動態圖(Dynamic Charts)
- 10.1 簡介
- 10.2 知識背景
- 10.3 實例應用
- 11 圖表工具條(Tooltips)
- 11.1 概述
- 11.2 創建圖表工具條
- 11.3 收集圖表工具條
- 11.4 顯示圖表工具條
- 11.5 隱藏圖表工具條
- 11.6 定制圖表工具條
- 12 圖表條目標簽(Item Label)
- 12.1 簡介
- 12.2 顯示條目標簽
- 12.3 條目標簽外觀
- 12.4 條目標簽位置
- 12.5 定制條目標簽文本
- 12.6 實例1
- 12.7 實例2
- 13 多軸和數據源圖表(Multi Axis and Dataset)
- 13.1 簡介
- 13.2 實例
- 13.3 建議和技巧
- 14 組合圖表(Combined Charts)
- 14.1 簡介
- 14.2 組合X種類圖區
- 14.3 組合Y種類圖區
- 14.4 組合X-XY圖區
- 14.5 組合Y-XY圖區
- 15 數據源和JDBC(Dataset And JDBC)
- 15.1 簡介
- 15.2 關于JDBC
- 15.3 樣本數據
- 15.4 PostgreSQL
- 15.5 JDBC驅動
- 15.6 應用演示
- 16 導出圖表為PDF格式
- 16.1 簡介
- 16.2 什么是Acrobat PDF
- 16.3 IText
- 16.4 Graphics2D
- 16.5 開始導出
- 16.6 實例應用
- 16.7 查看PDF 文件
- 16.8 Unicode字符問題
- 17 導出圖表為SVG格式
- 17.1 簡介
- 17.2 背景
- 17.3 實例代碼
- 18 Applet
- 18.1 簡介
- 18.2 問題
- 18.3 實例應用
- 19 Servlets
- 19.1 介紹
- 19.2 編寫一個簡單的Servlet應用
- 19.3 編譯實例Servlet
- 19.4 部署實例Servlet
- 19.5 在HMTL頁面種嵌入圖表
- 19.6 支持文件
- 19.7 部署Servlets
- 20 JFreeChart相關技術
- 20.1 簡介
- 20.2 X11/Headless Java
- 20.3 JSP
- 20.4 加載圖片
- 21 包
- 21.1 概述