プログラマー向けJavaチートシート3. Javaのコレクション(標準、グアバ、Apache、Trove、GSコレクションなど)

今日は、Javaのコレクションについてお話したいと思います。 このトピックは、Java開発者のほぼすべての技術面接で見つかりますが、すべての開発者が標準ライブラリでさえすべてのコレクションを完全にマスターしているわけではありません。もちろん、グアバ、Apache、Troveなどのコレクションの代替実装を持つすべてのライブラリはもちろんです。 Javaの世界で見つけられるコレクションと、それらを操作する方法がどのように存在するかを見てみましょう。



この記事は、初心者にとって(コレクションが何であるか、コレクションをどのように扱うかについての一般的な理解を得るために)、また役に立つコレクションを見つけたり、単に知識を構築したりする経験豊富なプログラマーの両方に役立ちます。 実際、主要なことは、どのプログラミング言語のコレクションについても少なくとも基本的な知識を持っていることです。これは、コレクションが原則として何であるかについての記事には説明がないためです。



I.標準Javaコレクションライブラリ



当然、ほとんどすべての人がすでにJDKのメインコレクションを知っていますが、それらについてはまだ覚えておいてください。標準コレクションに関するすべてを既に知っていることが確実な場合は、ネタバレのすべてを次のセクションに安全にスキップできます。

初心者向けコレクションノート
初心者にとって(特に他のプログラミング言語から切り替えた場合)、Javaコレクションに保存されているのはリンク/ポインターのみであり、それ以上のものではないことを理解するのが非常に難しい場合があります。 addまたはputを呼び出すと、オブジェクトは実際にはコレクション内のどこかに格納されているようです。これは、プリミティブ型で動作する配列にのみ当てはまり、リンクのみを格納するコレクションには当てはまりません。 そのため、「ArrayListコレクションの正確なサイズに名前を付けることはできますか?」などのインタビューの質問に対して、初心者は「保存されているオブジェクトの種類に依存する」などの質問に答え始めます。 コレクションはオブジェクト自体を保存せず、オブジェクトへのリンクのみを保存するため、これは完全に間違っています。 たとえば、同じオブジェクトをリストに100万回追加できます(より正確には、1つのオブジェクトに100万のリンクを作成します)。

1)JDKコレクションインターフェイス
JDKコレクションインターフェイス
収集インターフェース
役職説明
反復可能コレクションにイテレータがあり、for(Type value:collection)でバイパスできることを意味するインターフェース。 ほとんどすべてのコレクション(マップを除く)
収集ほとんどのコレクションのメインインターフェイス(マップを除く)
一覧リストは順序付けられたコレクションであり、シーケンスとも呼ばれます。
(シーケンス)。 ほとんどの実装で要素の重複は許可されています。 アクセスを許可します
要素インデックス。 コレクションインターフェイスを拡張します。
セットセットでの作業を実装するインターフェース(数学セットに類似)、複製
アイテムは禁止されています。 注文する場合としない場合があります。 コレクションインターフェイスを拡張します。
キューキューは、コレクションに対する通常の操作とは異なり、処理前にオブジェクトを保存することを目的としたコレクションです。キューは、追加、受信、表示のための追加メソッドを提供します。 原則として、要素インデックスによるクイックアクセスには含まれません。 コレクションインターフェイスを拡張
デケ双方向キュー。両端からの要素の追加と削除をサポートします。 展開する
キューインターフェイス。
地図キーと値のマッチングで動作します。 各キーは1つの値にのみ対応します。 で
他のコレクションとは異なり、インターフェイス(CollectionおよびIterableを含む)は拡張されません。
ソート済みセット自動的にソートされたセット、または自然順(詳細については、
比較可能なインターフェース)、またはComparatorを使用します。 セットインターフェイスを拡張
ソート済みマップこれは、キーが種類ごとまたは使用して自動的にソートされるマップです
コンパレータ Mapインターフェースを拡張します。
ナビゲーション可能セット
これは、指定された検索値に最も近い値を見つけるためのメソッドが追加されたSortedSetです。 NavigableSetにアクセスしてバイパスまたは順番に実行できます
値の降順または昇順。
ナビ可能マップ
これはSortedMapであり、特定の検索値に最も近い値を見つけるためのメソッドを追加しました。 降順または
昇順。

java.util.concurrentパッケージのインターフェース
役職説明
ブロッキングキュー
キューのサイズ、条件付きロック、受信時のデータの追加時またはデータの不足時のオーバーフローを処理するさまざまなメソッドを設定する機能を含むマルチスレッドキューの実装(例外をスローする、スレッドを永続的または一時的にブロックする、falseを返すなど)
TransferQueue
このマルチスレッドキューは、受信スレッドが要素をキューからプルするまで挿入スレッドをブロックできるため、スレッド間の同期および非同期メッセージ転送の実装に使用できます。
Blockingdeque
BlockingQueueに似ていますが、双方向キュー用です
コンカレントマップ
インターフェース、Mapインターフェースを拡張します。 多数の新しいアトミックメソッドを追加します:putIfAbsent、remove、replace。マルチスレッドプログラミングを簡単かつ安全にします。
並行ナビゲーション可能マップ
マルチスレッドバージョン用にNavigableMapインターフェースを拡張

java.util.concurrentのインターフェースおよびコレクションに関する詳細情報に興味がある場合は、
こちらの記事をご覧ください

2)すべてのコレクションの非常に簡単な説明を含む表
すべてのコレクションの非常に簡単な説明を含む表
種類シングルスレッドマルチスレッド
リスト
  • ArrayList-配列に基づくメインリスト
  • LinkedList-まれなケースでのみ有用です。
  • ベクトル-非推奨

  • CopyOnWriteArrayList-まれな更新、頻繁な読み取り

キュー/
Deques
  • ArrayDeque-配列に基づくメイン実装
  • スタック-非推奨
  • PriorityQueue-ソートされたキュー

  • ArrayBlockingQueue-ブロッキングキュー
  • ConcurrentLinkedDeque / ConcurrentLinkedQueue-関連ノードのキュー
  • DelayQueue-各アイテムの遅延キュー
  • LinkedBlockingDeque / LinkedBlockingQueue-関連ノードのブロッキングキュー
  • LinkedTransferQueue-要素の転送に使用できます
  • PriorityBlockingQueue-マルチスレッドPriorityQueue
  • SynchronousQueue-シンプルなマルチスレッドキュー

地図
  • HashMap-メインの実装
  • EnumMap-キーとして列挙
  • ハッシュテーブル-非推奨
  • IdentityHashMap-キーは==を使用して比較されます
  • LinkedHashMap-広告掲載オーダーを保存します
  • TreeMap-各種キー
  • WeakHashMap-キャッシュに役立つ弱いリンク

  • ConcurrentHashMap-メインのマルチスレッド実装
  • ConcurrentSkipListMap-ソートされたマルチスレッド実装

セット
  • HashSetは多くの主要な実装です
  • EnumSet-多くの列挙
  • BitSet *-多くのビット
  • LinkedHashSet-挿入順序を保持
  • TreeSet-ソートセット
  • ConcurrentSkipListSet-ソートされたマルチスレッドセット
  • CopyOnWriteArraySet-まれな更新、頻繁な読み取り


*-実際には、BitSetはSetと呼ばれますが、Setインターフェイスは継承しません。

3)JDKの非推奨のコレクション
非推奨のJavaコレクション
廃止(レガシー)と見なされる汎用ユニバーサルコレクション
説明
ハッシュテーブル
当初はHashMapの同期アナログとして考えられていましたが、まだ可能ではありませんでした
Collecions.synchronizedMapを使用してコレクションのバージョンを取得します。 現時点では、原則として
ConcurrentHashMapを使用します。 HashTableは同期よりも遅く、スレッドセーフではありません
HashMap。完全なレベルではなく、個々の操作のレベルで同期を提供します。
コレクション。
ベクトル以前はArrayListの同期バージョンとして使用されていましたが、次の理由と同じ理由で廃止されました
ハッシュテーブル
スタック以前はキューの構築に使用されていましたが、ベクターに基づいて構築されているため、
また、道徳的に時代遅れと見なされます。

従来のコレクションに基づいて構築された特殊なコレクション
に基づいて説明
物性
ハッシュテーブルHashtableに基づいて構築されたデータ構造として、Propertiesはかなり時代遅れの構造です。
文字列を含むマップを使用することをお勧めします。 プロパティの詳細
この議論で推薦されない使用を見つけることができます。
UIDefaults
ハッシュテーブルSwingコンポーネントのデフォルト設定を保存するコレクション


4) リストインターフェイスを実装するコレクション
Listインターフェースを実装するコレクション
リストを実装する汎用ユニバーサルコレクション:
役職によって設立されました

説明サイズ*
配列リスト
一覧動的に変化する配列に基づいたListインターフェイスの実装。 ほとんどの場合、Listインターフェイスの最適な実装は、メモリ消費とパフォーマンスです。 非常にまれなケースで、リストの先頭または中央に非常に小さい文字列を頻繁に挿入する必要がある場合
リスト上の移動回数により、LinkedListはパフォーマンスの向上につながります(ただし、これらの場合は、ApacheのTreeListを使用することをお勧めします)。 詳細が興味深いArrayListである場合、この記事を参照することをお勧めします。
4 * N
LinkedList
一覧双方向リンクリストに基づいたListインターフェイスの実装。つまり、各要素が前の要素と次の要素を指している場合。 原則として、ArrayListよりも多くのメモリとパフォーマンスが必要です。リスト内の最小の移動でリストの中央での挿入/削除が必要になることが多いまれな場合にのみ使用するのが理にかなっています(ただし、これらの場合はApacheからTreeListを使用することをお勧めします。 Dequeインターフェイス。 Queueインターフェイスを介して作業する場合、LinkedListはFIFOキューとして機能します。 LinkedListの詳細に興味がある場合は、この記事を参照することをお勧めします。
24 * N

java.util.concurrentパッケージのコレクション
役職によって設立されました

説明
CopyOnWriteArrayList
一覧ArrayListに似たListインターフェイスの実装ですが、リストが変更されるたびに作成されます
コレクション全体の新しいコピー。 これには、コレクションが変更されるたびに非常に大きなリソースが必要です。
ただし、このタイプのコレクションでは、コレクションが
反復時間。

リストに基づく高度に専門化されたコレクション。
役職に基づいて説明
役割リスト
配列リストロール(ロール)のリストを保存するためのコレクション。 に基づいた高度に専門化されたコレクション
いくつかの追加メソッドを持つArrayList
RoleUnresolvedList
配列リスト未解決のロール(未解決のロール)のリストを保存するためのコレクション。 高度に専門化された
ArrayListベースのコレクションといくつかの追加メソッド
AttributeList
配列リストMBean属性を格納するためのコレクション。 ArrayListに基づく高度に専門化されたコレクション
いくつかの追加の方法で

*-サイズは32ビットシステムおよび圧縮Oopsのバイト単位で指定されます。Nはリストの容量です

5) Setインターフェースを実装するコレクション(多く)
Setインターフェイスを実装するコレクション(多く)
役職によって設立されました

説明サイズ*
ハッシュセットセットハッシュテーブルを使用したSetインターフェイスの実装。 ほとんどの場合、Setインターフェイスの最適な実装が可能です。
32 * S + 4 * C
LinkedHashSet
ハッシュセットハッシュテーブルとリンクリストに基づくSetインターフェイスの実装。 HashSetとほぼ同じ速度で動作するアドオンセット。 一般に、HashSetとほぼ同じです。セットに対する反復の順序のみが、要素を追加する順序によって決定されます
初めて設定します。
40 * S + 4 * C
ツリーセットナビゲーション可能セット
赤黒木を使用したNavigableSetインターフェイスの実装。 コンパレータまたは自然順序を使用してソートされます。つまり、ソート規則に応じて複数のトラバーサル/反復が発生します。 HashMapに基づくHashSetのようなTreeMapに基づく
40 * S
Enumsetセットビットベクトルに基づくSetベクトルインターフェイスの高性能実装。 EnumSetオブジェクトのすべての要素は、1つの単一の列挙型に属している必要があります
S / 8

*-サイズは、32ビットシステムおよび圧縮Oopsのバイト単位で指定されます。Cはリストの容量、Sはリストのサイズです

セットに基づく特別なコレクション
役職によって設立されました

説明
JobStateReasons
ハッシュセット印刷ジョブに関する情報(印刷ジョブの属性セット)を保存するためのコレクション。
いくつかの追加メソッドを備えたHashSetに基づく高度に専門化されたコレクション

java.util.concurrentパッケージのコレクション
役職によって設立されました

説明
CopyOnWriteArraySet
セット同様に、CopyOnWriteArrayListは変更ごとにセット全体のコピーを作成するため、
非常にまれなコレクションの変更およびスレッドセーフ要件に推奨
ConcurrentSkipListSet
セットTreeSetのマルチスレッドアナログです。


6) Mapインターフェイスを実装するコレクション(連想配列)
Mapインターフェースを実装するコレクション
Mapを実装する汎用汎用コレクション:
役職によって設立されました

説明サイズ*
ハッシュマップ地図ハッシュテーブルを使用したMapインターフェイスの実装(非同期Hashtableとして機能し、
キーとnull値のサポート)。 ほとんどの場合、最高のパフォーマンスと
Mapインターフェイスのメモリ実装。 HashMapデバイスの詳細が興味深い場合は、この記事を参照することをお勧めします。
32 * S + 4 * C
LinkedHashMap
ハッシュマップハッシュテーブルとリンクリスト、つまりマップ内のキーに基づいたMapインターフェイスの実装
追加された順に保存およびバイパスされます。 このコレクションはほぼ同じくらい高速です
ハッシュマップ また、キャッシュの作成にも役立ちます(
removeEldestEntry(Map.Entry))。 LinkedHashMapデバイスの詳細が興味深い場合は、この記事を参照することをお勧めします。
40 * S + 4 * C
ツリーマップナビ可能マップ
赤黒ツリーを使用したNavigableMapの実装、つまりコレクション、キーをトラバースするとき
同じNavigableMapを使用すると、キーに最も近い値を検索できます。
40 * S
弱点マップ
地図HashMapと同様ですが、すべてのキーは弱いです
弱い参照、つまりガベージコレクションにより、オブジェクトのキーとオブジェクトが削除される可能性があります
これらのオブジェクトへの他の参照が存在しない場合の値。 WeakHashMapは最も簡単なものの1つです
弱いリンクを最大限に活用する方法。
32 * S + 4 * C
Enummap地図単純な配列に基づいたMapインターフェースの高性能実装。 すべてのキー
このコレクションは、1つの列挙型にのみ属することができます。
4 * C
IdentityHashMap
地図HashMapのようなIDベースのマップはハッシュテーブルに基づいていますが、HashMapとは異なり、
等しいオブジェクトを比較することはありません。実際に同じかどうかのみを比較します
メモリ内のオブジェクト。 第一に、コレクションの作業を大幅に高速化し、第二に、
等しいが別のオブジェクトによって意図的に生成される場合の「スプーフィング攻撃」に対する保護。
第三に、このコレクションには、グラフをトラバースするときに多くの用途があります(ディープコピーなど)
1つのオブジェクトを複数回処理することを避ける必要がある場合。
8 * C

*-サイズは32ビットシステムおよび圧縮Oopsのバイト単位で指定されます。Cはリストの容量、Sはリストのサイズです

java.util.concurrentパッケージのコレクション
役職によって設立されました

説明
並行ハッシュマップ
コンカレントマップ
HashMapのマルチスレッドアナログ。 すべてのデータは個別のセグメントに分割され、ブロックされるのみ
変更時の個々のセグメント。マルチスレッドでの作業を大幅に高速化します
モード。 イテレータは、このタイプのコレクションに対してConcurrentModificationExceptionをスローすることはありません。
ConcurrentSkipListMap
並行ナビゲーション可能マップ
TreeMapのマルチスレッドの類似物です


7) キュー/デキューインターフェイス (キュー)に基づくコレクション
キュー/デキューベースのコレクション
役職によって設立されました

説明サイズ*
配列
デケ動的配列に基づくDequeインターフェースの効率的な実装、類似
配列リスト
6 * N
LinkedList
デケ双方向リンクリストに基づくList and Dequeインターフェイスの実装、つまり、各要素が前の要素と次の要素を指す場合、Queueインターフェイスを介して作業する場合、LinkedListはFIFOキューとして機能します。
40 * N
PriorityQueue
キューヒープ(ヒープ)に基づく無制限の優先度キュー。 ソートされたアイテム
わかりましたまたはコンパレータを使用して。 null要素を含めることはできません。

*-サイズは、32ビットシステムおよび圧縮Oopsのバイト単位で指定されます。Cはリストの容量、Sはリストのサイズです

java.util.concurrentで定義されているマルチスレッドキューとデックには別の記事が必要なので、ここでは説明しません。これらの情報に興味がある場合は、この記事を読むことをお勧めします。


8)その他のコレクション
その他のコレクション
役職説明サイズ*
ビットセット
その名前にもかかわらず、BitSetはSetインターフェイスを実装しません。 BitSetは、ビット配列のコンパクトな記録に使用されます。
N / 8


9)コレクションを操作する方法
コレクションメソッド
アルゴリズム-コレクションクラスには、多くの便利な統計手法が含まれています。
コレクションを操作するには:
方法説明
頻度 (コレクション、オブジェクト)
指定されたコレクション内のこの要素の出現回数を返します。
disjoint (コレクション、コレクション)2つのコレクションに共通の要素がない場合、trueを返します。
addAll (コレクション<?スーパーT>、T ...)指定された配列(またはパラメーターにリストされている)のすべての要素を指定されたコレクションに追加します
min (コレクション)コレクションから最小アイテムを返します
max (コレクション)コレクションから最大のアイテムを返します


リストを使用するには:
方法説明
ソート (リスト)ほとんどの場合、パフォーマンスが高品質のクイックソートのパフォーマンスに近いマージソートアルゴリズムを使用したソートにより、O(n * log n)パフォーマンス(クイックソートではなく)と安定性(クイックソート)。 安定したソートは、ソート時に同じ要素の順序を変更しないものです
binarySearch (リスト、オブジェクト)バイナリ検索アルゴリズムを使用して、リスト内のアイテムを検索します。
リバース (リスト)すべてのリストアイテムを並べ替える
シャッフル (リスト)リスト内のすべてのアイテムをランダムにシャッフルします
fill (リスト、オブジェクト)リスト内の各アイテムを値で上書きする
コピー (リスト送信先、リスト送信元)あるリストを別のリストにコピーする
回転 (リストリスト、int距離)リスト内のすべてのアイテムを指定された距離だけ移動します。
replaceAll (リストリスト、オブジェクトoldVal、オブジェクトnewVal)ある値のすべての出現を別の値に置き換えます
indexOfSubList (リストソース、リストターゲット)ソースリストでターゲットリストが最初に現れるインデックスを返します
lastIndexOfSubList (リストソース、リストターゲット)ソースリスト内のターゲットリストの最後の出現のインデックスを返します
スワップ (リスト、int、int)指定された位置にある要素を交換します

Java 8では、ストリームApiなどのコレクションを操作する方法も導入されましたが、その使用例についてはセクション5で後述します。

10)さまざまなタイプのJDKコレクションは内部でどのように配置されますか
さまざまなタイプのJDKコレクションは内部でどのように配置されますか
収集内部デバイスの説明
配列リストこのコレクションは、配列の設定+リストのサイズを格納する変数です。 中だけ
新しい要素を追加する場所がないたびに再作成される配列。 で
コレクション内の要素を追加または削除する場合、メモリ全体でテール全体がシフトされます
新しい場所。 幸いなことに、容量を増やしながら、または追加/削除するときにアレイをコピーします
高速なネイティブ/システムメソッドによって生成される要素。 詳細が興味深い場合
この記事をご覧になることをお勧めします。
LinkedListコレクション内では、前の要素へのリンクを含む内部Nodeクラスが使用され、
次の要素と要素自体の値。 コレクションインスタンス自体にサイズとリンクが格納されます
コレクションの最初と最後の要素。 オブジェクトを作成することは、
パフォーマンスとメモリを集中的に使用するLinkedList
アナログよりもはるかに多くのメモリ。 通常、ArrayList、ArrayDequeryはパフォーマンスとメモリの最適なソリューションですが、まれなケース(リストの中央に頻繁に挿入され、リスト内のまれな動きが発生する)が役立つ場合があります(ただし、この場合はapacheからTreeListを使用する方が便利です)。 詳細が興味深い場合は、この記事をご覧になることをお勧めします。
ハッシュマップこのコレクションは、ハッシュテーブル上に構築されます。つまり、コレクション内には、コレクションの容量に等しい内部クラス(バケット)ノードの配列があります。 新しい要素を追加すると、そのハッシュ関数が計算され、キャパシティHashMapモジュロで除算されるため、配列内の要素の位置が計算されます。 この場所に要素がまだ保存されていない場合、追加された要素へのリンクを含む新しいNodeオブジェクトが作成され、配列内の目的の場所に書き込まれます。 この場所に既に要素が存在する場合(ハッシュ衝突が発生する場合)、Nodeは基本的に単純にリンクされたリストです。つまり、次の要素へのリンクが含まれます。リスト内のすべての要素をバイパスし、追加された要素と等しいかどうかを確認できますそのような一致が見つからなかった場合、新しいNodeオブジェクトが作成され、リストの最後に追加されます。 リンクリスト(バケット)の要素の数が8個を超える要素になると、代わりにバイナリツリーが作成されます。 ハッシュテーブルの詳細については、 wikiを参照してください(HashMapはチェーンメソッドを使用して衝突を解決します)。 HashMapデバイスの詳細が興味深い場合は、この記事を参照することをお勧めします。
ハッシュセットHashSetは単なるHashMapであり、値の代わりに偽のオブジェクトが書き込まれ、キーのみが重要です。 HashSet内には、HashMapコレクションが常に保存されます。
IdentityHashMapIdentityHashMapはHashMapに類似していますが、要素が等しいかどうかをチェックする必要がないため、
2つの要素の違い。 異なるオブジェクトを指します。 これのおかげで、
内部クラスNodeを取り除き、すべてのデータを1つの配列に格納し、衝突が発生する
適切な空きセルが見つかるまで検索されます( メソッド
オープンアドレッシング )ハッシュテーブルの詳細については、 wikiを参照してください
(IdentityHashMapはオープンアドレッシングメソッドを使用して衝突を解決します)
LinkedHashMap / LinkedHashSet内部構造はHashMapとほぼ同じですが、代わりに
内部クラスNode、TreeNodeを使用します。TreeNodeは前の値と次の値を知っています。
これにより、キーを追加する順序でLinkedHashMapをバイパスできます。 基本的にLinkedHashMap =
HashMap + LinkedList。 LinkedHashMapデバイスの詳細に興味がある場合は、この記事を参照することをお勧めします。
TreeMap / TreeSetこれらのコレクションの内部構造は、バランスの取れた赤黒のツリー上に構築され、
wikiで詳細を読む
弱点マップ内部では、通常のリンクではなく、すべてがHashMapのように整理されています
WeakReferenceが使用され、削除に必要な別のReferenceQueueキューがあります
弱いエントリ
EnumSet / EnumMapEnumSetとEnumMapは、HashSetやHashMapとは異なり、ビットベクトルと配列を使用して
データストレージをコンパクトにし、パフォーマンスを向上させます。 これらのコレクションの制限は
EnumSetとEnumMapは、1つのEnumの値のみをキーとして保存できます。


11)標準コレクションライブラリの他の有用なエンティティ
標準コレクションライブラリの他の有用なエンティティ
公式のコレクションガイドに含まれる他の有用なエンティティを見てみましょう
1) ラッパー実装 -機能を追加し、他の実装の動作を変更するためのラッパー。 統計的手法のみを使用してアクセスします。
  • Collections.unmodifiableInterface-指定されたコレクションに基づいて変更不可能なコレクションを作成するためのラッパー。このコレクションを変更しようとするとUnsupportedOperationExceptionがスローされます
  • Collections.synchronizedInterface-指定に基づいて同期コレクションを作成します。ベースコレクションへのアクセスがこの関数によって返されるコレクションラッパーを介している限り、スレッドセーフが保証されます。
  • Collections.checkedInterface-型チェック付きのコレクションを動的に返します
    (実行時)、つまり、指定されたコレクションのタイプセーフビューを返します。
    間違った型の要素を追加しようとすると、ClassCastExceptionがスローされます。 使用する場合
    汎用JDKメカニズムは、コンパイルレベルで型のコンパイルをチェックしますが、このメカニズム
    バイパスすることができ、動的な型チェックではこの機会を利用できません。


2) アダプタの実装 -この実装は、1つのコレクションインターフェイスを別のコレクションインターフェイスに適合させます
  • newSetFromMap(Map)-Setインターフェースの実装からMapインターフェースの実装を作成します。
  • asLifoQueue(Deque)-Dequeからのビューを、Last In First Out(LIFO)の原理に基づいたキューとして返します。

3) 便利な実装 -コレクションインターフェイスの高性能な「ミニ実装」。
  • Arrays.asList-配列をリストとして表示できます
  • emptySet、emptyList、およびemptyMap-空のセット、リスト、または空の未変更の実装を返します。
    地図
  • singleton、singletonList、singletonMap -1つの指定されたオブジェクト(または1つのキーと値の関係)を含む変更不可能なセット、リスト、またはマップを返します
  • nCopies-指定されたオブジェクトのn個のコピーを含む変更不可能なリストを返します

4) インターフェイスの抽象的な実装 -コレクションの特定の実装の作成を簡素化するための共通機能(コレクションのスケルトン)の実装。
  • AbstractCollection-セットでもリストでもないコレクション(「バッグ」やマルチセットなど)のCollectionインターフェイスの抽象実装。
  • AbstractSet -Setインターフェイスの抽象的な実装。
  • AbstractList-配列などのランダムアクセスを許可するリストのListインターフェイスの抽象的な実装。
  • AbstractSequentialList-リンクリストなどのシーケンシャルアクセスベースのリスト用のListインターフェイスの抽象的な実装。
  • AbstractQueue-抽象キューの実装。
  • AbstractMap-抽象マップの実装。

4) インフラ
  • イテレータ -通常の列挙インターフェイスに似ていますが、優れた機能を備えています。
  • Iterator -Enumerationインターフェイス機能に加えて、コレクションからアイテムを削除する機能が含まれます。
  • ListIteratorはリストに使用されるイテレーターで、双方向の反復、要素の置換、要素の挿入、インデックスによる取得など、通常のイテレーターインターフェイスの機能を追加します。

5)注文
  • 比較可能 -それらを実装するクラスの自然なソート順を定義します。 この順序は、ソート方法で使用するか、ソートされたセットまたはマップを実装するために使用できます。
  • Comparator-順序関係を表します。これは、ソートされたセットまたはマップ内のリストまたはメイン順序をソートするために使用できます。 型の自然な順序をオーバーライドしたり、Comparableインターフェイスを実装していない型のオブジェクトを順序付けたりできます。

6)ランタイム例外
  • UnsupportedOperationException-このエラーは、コレクションが呼び出された操作をサポートしていない場合にスローされます。
  • ConcurrentModificationException-イテレータまたはリストイテレータをスローします。イテレータが基づいているコレクションが(アルゴリズムの場合)反復中に予期せず変更された場合、メインリストが予期せず変更された場合はリストに基づいたビューもスローします

7)パフォーマンス
  • RandomAccess-リストをマークするマーカーインターフェイスは、位置によって要素にすばやく(通常は一定時間)アクセスできるようにします。 これにより、シーケンシャルアクセスと位置アクセスの選択に関するこの動作を考慮したアルゴリズムを生成できます。

8)配列を操作するためのユーティリティ
  • 配列 -配列のハッシュをソート、検索、比較、サイズ変更、取得するための静的メソッドのセット。 また、配列を文字列に変換し、配列をプリミティブまたはオブジェクトで埋めるためのメソッドも含まれています。



II。 サードパーティのコレクションライブラリの概要



したがって、次のサードパーティライブラリを確認したいと思います:guava、apache、trove、gs-collections。 なぜこれらのライブラリーなのか? GuavaとApache Commonsコレクションは非常に人気があり、ほとんどすべてのJavaプロジェクトで出会いました。Troveは、メモリを削減し、コレクションを操作するパフォーマンスを向上させる必要があるときに非常に人気のあるライブラリです。 GSコレクション-github'eで非常に人気のあるライブラリ(1300以上の星)の見積もりから判断すると、グアバだけがそれよりも多くの「星」を獲得しました。 他のいくつかの人気のあるライブラリを垣間見るだけです。

したがって、まず最初に、さまざまなライブラリが提供する主な機能を考慮してください(警告:これは非常に主観的です。一部の人々にとって、主な機能は完全に異なるライブラリ機能になります)。

2.1さまざまなコレクションライブラリのチップ



さまざまなコレクションライブラリの主な機能(私の意見では)を簡単に確認しましょう。
1) グアバ-Googleのこのコレクションは、標準のコレクションフレームワークに次いでほぼ最も人気があります。
いくつかの興味深いコレクションを追加しますが、最も重要な「トリック」は、静的なユーティリティクラスの豊富なセットです。
コレクションの機能を拡張して、新しいタイプのコレクションよりも標準コレクションで機能するメソッド。
実際には、標準のコレクションは置き換えられません。

2) Apache Commons Collections-このコレクションは、グアバに最も近い「競合他社」であり、多くの
興味深いコレクション、標準Javaコレクションを操作するためのユーティリティ、および多数のラッパー
コレクションの動作の変更。 さらに、よりシンプルなメカニズムでマップの実装を提供します。
それを繰り返します。

3) Trove-このコレクションの機能は、主にパフォーマンスとメモリの削減にあるため、
標準コレクションの高速な実装(および必要なメモリが少ない)とコレクションを提供します
プリミティブ型。

4) GSコレクション -このコレクションの特徴は、ソートやクラスなどの処理方法を組み合わせることです。
ユーティリティクラスの静的メソッドを使用するための代替を作成するコレクション。 このライブラリは代替品を提供します
ほとんどすべての標準コレクションといくつかの新しいコレクションが追加されます。

III。 異なるライブラリの代替タイプのコレクション



ここでは、さまざまなライブラリでどのような新しい興味深いコレクションが見つかるかを簡単に考えてみます。

3.1グアバの代替収集タイプ


公式情報: ドキュメントソースコードjavadoc
プロジェクトへの接続方法:
メイヴン、グラドル
メイヴン
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> </dependency> 


グラドル
 dependencies { compile 'com.google.guava:guava:18.0' } 



Googleは、既存のコレクションにいくつかの興味深い追加機能を開発しました。これらの機能は、できれば非常に便利です。
プロジェクトでguavaライブラリを使用します。 これらのコレクションは、長い間事実上の標準になっていると言えます。
ほとんどのJavaプロジェクトでは、経験豊富な開発者にとっては、何らかの理由でプロジェクトを知ることが重要です。
理由は彼らのプロジェクトでそれらを使用することはできません、多くの場合、インタビューでグアバについての質問を聞くことができます
コレクション。

それらをさらに詳しく見てみましょう。 まず、グアバのメインコレクションとクラスグループのインターフェイスを見てみましょう。

注意 :テーブルが全体に収まらない場合は、ページをズームアウトするか、別のブラウザーで開いてみてください。
役職説明実装例使用例
ImmutableCollection
ImmutableList
ImmutableSet
...など
標準のJavaコレクションフレームワークには、呼び出しによってコレクションを不変にする機能がありますが
Collections.unmodifiableCollection(unmodifiableListまたはunmodifiableMap)、しかしこのアプローチは最も
不変のコレクションに別の型を使用すると、それが確実にできるため、最適
コレクションを変更しようとすると、ランタイムエラーの代わりにコレクションは本当に不変です。
プロジェクトのコンパイル中にエラーが発生します。さらに、標準のJavaコレクションフレームワークでは不変です
コレクションは、マルチスレッド読み取りなどの同期をサポートするリソースを依然として使用しています。
ImmutableCollection guavaは、それらが不変であり、最適化されていることを「認識」しています
これを与えられた。
JDK: ImmutableCollection
ImmutableList
ImmutableSet
ImmutableSortedSet
ImmutableMap
ImmutableSortedMap
グアバ: ImmutableMultiset
ImmutableSortedMultiset
ImmutableMultimap
ImmutableListMultimap
ImmutableSetMultimap
ImmutableBiMap
ImmutableClassToInstanceMap
ImmutableTable
-publicメソッドが、他のクラスが変更されないことが保証されているコレクションを返す場合、
-コレクションの値が再び変更されることがないことがわかっている場合
マルチセット
コレクションはSetに似ていますが、要素への追加の数をさらにカウントできます。 とても
特定の要素が特定のセットに含まれているかどうかだけでなく、
その数を数える(最も簡単な例は、特定の単語の言及の数を数えることです
任意のテキスト)。 つまり、このコレクションはMap <T、Integer>コレクションのより便利なバージョンであり、そのようなコレクション用に特別に設計されたメソッドにより、
そのような場合には余分なコードの量を減らしてください。
HashMultiset
TreeMultiset
LinkedHashMultiset
ConcurrentHashMultiset
ImmutableMultiset
並べ替え
-テキスト内の単語の出現回数のカウント
-テキスト内の文字数を数える
-オブジェクトの数を数える
マルチマップ
ほとんどの経験豊富なJava開発者は、Map <K、List <V >>またはMap <K、Set <V >>などの構造を使用する必要に直面しましたが、作業を簡素化するために多くの追加コードを作成する必要がありましたが、Multimapはguavaライブラリに導入され、次の場合に簡単に作業できるコレクションがあります
1つのキーと、このキーの多くの値。 Map <K、Set <V >>のような構造とは異なり、Multimapは、コードの削減とアルゴリズムの簡素化のための便利な機能を多数提供します。
ArrayListMultimap
HashMultimap
LinkedListMultimap
LinkedHashMultimap
TreeMultimap
ImmutableListMultimap
ImmutableSetMultimap
-次のような1対多の関係の実装
教師-学生
部門-労働者
チーフ-部下
バイマップ
多くの場合、両方向で機能するマップを作成したい場合があります。
キーと意味が場所を変更できる場合(たとえば、ロシア語-英語辞書、ある場合
ロシア語で受信する必要があります-英語、別の逆に英語-ロシア語)。 通常これ
これは、2つのマップを作成することで解決されます。1つにはkey1-key2、もう1つにはkey2-key1)。 BiMapでは
1つのコレクションだけでこの問題を解決します。 さらに、問題とエラーを排除します。
2つのコレクションを使用する場合の同期。
HashBiMap
ImmutableBiMap
EnumBiMap
EnumHashBiMap
-ある言語から別の言語へ、またはその逆の翻訳用の辞書、
-双方向のデータ変換、
テーブル
このコレクションは、Map <FirstName、Map <LastName、Person >>、という形式のコレクションを置き換えます。
使用するには不便です。
HashBasedTable
TreeBasedTable
ImmutableTable
ArrayTable
-たとえば、Excelのようなテーブル
-多数の列を持つ複雑なデータ構造、
ClassToInstanceMap
時々、Map'eにキー値ではなく、このタイプのタイプ値を保存する必要があります。この目的のために、
コレクション。 つまり、技術的にはMapのより便利で安全な類似物です。
<クラス
<? B>、B>を拡張
MutableClassToInstanceMap
ImmutableClassToInstanceMap
レンジセット
数値の異なる開いたセグメントと閉じたセグメントを格納するコレクション。セグメントは
互いに団結します。
ImmutableRangeSet
TreeRangeSet
幾何学的セグメント
期間
レンジマップ
RangeSetに似たコレクションですが、セグメントが互いに結合されることはありません。ImmutableRangeMap
TreeRangeMap
幾何学的セグメント
期間
LoadingCache
ConcurrentMapに似たコレクションですが、同時にそれぞれを保存する時間を指定できます
アイテム。 キャッシュを整理するための非常に便利なコレクションで、不正なパスワードエントリの数をカウントします
一定期間など タスク
ForwardingLoadingCache
ForwardingLoadingCache.SimpleForwardingLoadingCache
キャッシュ
誤った保管
パスワードの試行
など


3.2 Apache Commonsコレクションからの新しいタイプのコレクション



公式情報ドキュメントソースコードユーザードキュメントjavadoc
プロジェクトへの接続方法:
メイヴン、グラドル、アイビー
メイヴン
 <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.0</version> </dependency> 


グラドル
 'org.apache.commons:commons-collections4:4.0' 

ツタ
 <dependency org="org.apache.commons" name="commons-collections4" rev="4.0"/> 



注意 :テーブルが全体に収まらない場合は、ページをズームアウトするか、別のブラウザーで開いてみてください。
役職説明実装例使用例
変更不可
Immutable guavaクラスに似たインターフェースUnmodifiableBag
UnmodifiableBidiMap
UnmodifiableCollection
UnmodifiableList
変更不可能なマップ
など
すべての場合において、変更されていないコレクションを作成する必要がある場合
Iterablemap
Mapインターフェースに類似していますが、エントリセットを作成せずにMapを直接反復処理できます。 使用されている
このライブラリのほぼすべてのMap実装で。
HashedMap
LinkedMap
ListOrderedMap
その他多数
通常の地図と同じ
OrderedMap
追加順にマップを作成できますが、並べ替えは使用できませんLinkedMap
ListOrderedMap
通常、個別にリストおよび個別に使用される場合
ビディマップ
GuavaのBiMapの類似物、つまり、キーごとに値を取得する機能、および値ごとにキーを取得する機能TreeBidiMap
DualHashBidiMap
DualLinkedHashBidiMap
DualTreeBidiMap
など
両側で実行する1対1の変換
バッグ
GuavaのMultisetの類似物、つまり、各タイプの要素の数を保存する機能CollectionBag
ハッシュバッグ
SynchronizedBag
ツリーバッグ
その他
オブジェクトの数を数える
BoundedCollection
境界マップ
上のサイズに制限された動的コレクションを作成できますCircularFifoQueue
FixedSizeList
FixedSizeMap
ラム
コレクションが特定の量を超えてはならないことが確実にわかっている場合
要素
マルチマップ
GuavaのMultimapアナログ、つまり、1つのキーに対して多くの要素を保存する機能MultiValueMap関連を持つコレクションの場合、1つのキー-多くの値
トライ
順序付けられたツリーを作成および保存するためのコレクションパトリシアトリー木を作る
ツリーリスト
リストの中央に要素を挿入する場合は、ArrayListとLinkedListを置き換えます。データはこのリストのツリーに格納されているため、インデックスによってデータを比較的迅速に受信できる一方、リストの中央にデータをすばやく挿入できます。ツリーリストLinkedListをリストの中央で頻繁に追加/ストレスに置き換える


3.3 Troveコレクション


代替コレクションの他のライブラリとは異なり、Troveは新しい独自のビューを提供しません。
コレクションが、既存の最適化を提供します:
まず、ご存じのように、プリミティブJava型は標準コレクションに追加できず、ラッパーのみが追加されます。これは劇的です
占有メモリが増加し、コレクションのパフォーマンスがわずかに低下します。 Troveはコレクションのコレクションを提供し、
プリミティブ型を含むキーと値。

第二に、標準コレクションはメモリ消費に最適な方法で実装されないことがよくあります。たとえば、各HashMap要素は個別のオブジェクトに格納され、HashSetはキーの代わりに偽のオブジェクトを格納するHashMapです。 Troveは、配列とオープンアドレッシングに基づいてこのようなコレクションの実装を提供します。これにより、必要なメモリが大幅に削減され、場合によってはパフォーマンスが向上します。

更新:コメントでは、すべての点(バグの数、インターフェイスの完全なカバレッジ、パフォーマンス、サポートアクティビティなど)でfastutilまたはGSに劣るので、新しいプロジェクトでTroveを使用することは悪いと記事は示唆しています。 残念ながら、現在TroveとfastutilおよびGSの完全な分析/比較を行う機会がないため、この意見を確認することはできません。代替コレクションのライブラリを選択する際に検討してください。

公式情報: ドキュメントソースコードjavadoc
プロジェクトへの接続方法:
メイヴン、グラドル、アイビー
メイヴン
 <dependency> <groupId>net.sf.trove4j</groupId> <artifactId>trove4j</artifactId> <version>3.0.3</version> </dependency> 


グラドル
 'net.sf.trove4j:trove4j:3.0.3' 

ツタ
 <dependency org="net.sf.trove4j" name="trove4j" rev="3.0.3"/> 


役職JDKアナログ説明
THashMapハッシュマップオープンアドレス指定 」アルゴリズムを備えたハッシュテーブルを使用して衝突を解決するMapインターフェイスの実装( 連鎖方法が使用されるHashMapとは異なります )。 これにより、メモリを大幅に節約し、場合によってはパフォーマンスを向上させながら、Nodeクラスのオブジェクトを保存または作成しないことができます。
タッシュセットハッシュセット衝突を解決するために「 オープンアドレッシング 」アルゴリズムを備えたハッシュテーブルを使用するSetインターフェイスの実装
TLinkedHashSetLinkedHashSetLinkedHashSetに似ていますが、「 オープンアドレス指定 」アルゴリズムでハッシュテーブルを使用します
TLinkedListLinkedListただし、リンクリストのより効率的な類似物であり、データにいくつかの制限を課しています。
TByteArrayList
TIntArrayListなど
配列リストプリミティブな数値を直接保存するArrayListの類似物で、メモリコストを大幅に削減し、処理を高速化します。 7つのすべてのプリミティブ数値型のコレクションがあり、名前テンプレートはT [Type] ArrayListです
TCharLinkedList
TFloatLinkedListなど
LinkedList7つのプリミティブ数値型、命名パターンT [Type] LinkedListを格納するLinkedListの類似物
TByteArrayStack
TLongArrayStack
配列プリミティブな数値型を格納するためのスタック実装、命名パターンT [Type] LinkedList
TIntQueue
TCharQueue
配列プリミティブな数値型を保存するためのキューの実装、命名パターンT [Type] Queue
TShortHashSet
TDoubleHashSet
ハッシュセットプリミティブ型を保存するためのSetインターフェイスの実装、 オープンアドレッシングアルゴリズム、名前テンプレートT [Type] HashSet
TLongLongHashMap
TFloatObjectHashMap
TShortObjectHashMapなど
ハッシュマップオープンアドレス指定アルゴリズム、命名パターンT [Type] [Type] HashMapのプリミティブ型を格納するためのMapインターフェイスの実装。


3.4 GSコレクションのコレクション


このライブラリの主な機能は、コレクションの処理(並べ替え、検索)のメソッドがコレクションクラス自体に追加されず、Collections.sortなどが使用されることは非論理的で見苦しいことです。 したがって、GSコレクションは、すべての処理、検索、およびソートのメソッドを格納する「リッチコレクション」のアイデアを提案しました。つまり、Collections.sort(リスト)の代わりに、list.sortのみが呼び出されます。 そのため、ライブラリは、標準コレクションの類似物に加えて、いくつかの新しいコレクションを提供しています。
公式情報ドキュメントソースコードユーザードキュメントjavadoc
プロジェクトへの接続方法:
メイヴン、グラドル、アイビー
メイヴン
 <dependency> <groupId>com.goldmansachs</groupId> <artifactId>gs-collections-api</artifactId> <version>6.2.0</version> </dependency> <dependency> <groupId>com.goldmansachs</groupId> <artifactId>gs-collections</artifactId> <version>6.2.0</version> </dependency> <dependency> <groupId>com.goldmansachs</groupId> <artifactId>gs-collections-testutils</artifactId> <version>6.2.0</version> <scope>test</scope> </dependency> <dependency> <groupId>com.goldmansachs</groupId> <artifactId>gs-collections-forkjoin</artifactId> <version>6.2.0</version> </dependency> 
グラドル

 compile 'com.goldmansachs:gs-collections-api:6.2.0' compile 'com.goldmansachs:gs-collections:6.2.0' testCompile 'com.goldmansachs:gs-collections-testutils:6.2.0' compile 'com.goldmansachs:gs-collections-forkjoin:6.2.0' 

ツタ
 <dependency org="com.goldmansachs" name="gs-collections-api" rev="6.2.0" /> <dependency org="com.goldmansachs" name="gs-collections" rev="6.2.0" /> <dependency org="com.goldmansachs" name="gs-collections-testutils" rev="6.2.0" /> <dependency org="com.goldmansachs" name="gs-collections-forkjoin" rev="6.2.0"/> 



役職JDKアナログ説明
ファストリスト配列リストソート、選択などの機能を使用できるArrayListの類似物。 コレクションオブジェクトで
統一セットハッシュセットHashSetアナログ。 FastListを参照
TreeSortedSetツリーセットアナログツリーセット。 FastListを参照
統合マップハッシュマップHashMapに類似しています。 FastListを参照
TreeSortedMapツリーマップアナログツリーマップ。 FastListを参照
HashBiMap-BiMapの実装、グアバを参照
ハッシュバッグ-マルチセット実装、グアバを参照
ツリーバッグ-ソートされたBiMapの実装、グアバを参照
アレイスタック配列Stack JDKクラスと同様に、「後入れ先出し」の順序でスタックを実装します
FastListMultimap-マルチマップの実装、グアバを参照
IntArrayList
FloatHashSet
ArrayStack
ハッシュバッグ
ByteIntHashMap
-プリミティブなさまざまなタイプのコレクション、命名の原則はtroveのそれと同じですが、JDKの類似物に加えて、Stack、Bagコレクションの類似物もあります


3.5 Fastutilコレクション



プリミティブ型のコレクションを扱うためのこのライブラリを非常に簡単に見てみましょう。
詳細は、 ドキュメントソースコードjavadocを参照してください。
役職説明
Byte2DoubleOpenHashMap、
IntArrayList、
IntArrayPriorityQueue
など
さまざまなプリミティブ型のコレクション、命名原則[Type] ArrayList、[Type] ArrayPriorityQueueなど。 リストまたはセット、および[KeyType] 2 [ValueType] OpenHashMapなど。 マップ用。
IntBigList、
DoubleOpenHashBigSetなど
非常に大きなサイズのさまざまなプリミティブタイプのコレクション。これらのコレクションでは、intではなく長い要素を使用できます。 内部では、データは通常配列の配列として保存されます。 パフォーマンスの損失は約30%に達する可能性があるため、通常のコレクションで十分な場合はそのようなコレクションを使用することはお勧めしませんが、このようなコレクションを使用すると、大量のデータを操作できます


3.6他のコレクションライブラリとプリミティブコレクションのパフォーマンスについて少し


TroveとFastutilに加えて、プリミティブ型のコレクションと標準コレクションの高速アナログを実装するいくつかの有名なライブラリがあります。
1) HPPC -Java用の高性能プリミティブコレクションは、JDKのコレクションに類似したプリミティブコレクションも提供します。
2) Koloboke (HFTCの別名)-名前が示すように、このプリミティブ型のライブラリは、 OpenHFTプロジェクトの一環としてロシアのプログラマー(Roman Leventov)によって開発されました。 このライブラリは、高性能なプリミティブコレクションの実装にも役立ちます。

さまざまなライブラリのパフォーマンスを比較することが興味深い場合は、この記事を参照することをお勧めします。特定の条件でテストされたのはHashMapコレクションのみであることを考慮する必要があります。 さらに、占有メモリを考慮せずに作業速度のみを測定しました(たとえば、HashMap jdkはtroveのアナログよりもはるかに多くのメモリを使用できます)。また、メモリはパフォーマンスよりもさらに重要になる場合があります。

更新:コメントでは、すべての点(バグの数、インターフェイスの完全なカバレッジ、パフォーマンス、サポートアクティビティなど)でfastutilまたはGSに劣るので、新しいプロジェクトでTroveを使用することは悪いと記事は示唆しています。 残念ながら、現在TroveとfastutilおよびGSの完全な分析/比較を行う機会がないため、この意見を確認することはできません。代替コレクションのライブラリを選択する際に検討してください。

IV。 さまざまなライブラリで最も人気のある代替コレクションの実装の比較



4.1グアバ、Apache Commons Collections、GSライブラリでのマルチセット(MultiSet / Bag)の実装
コレクション


したがって、マルチセットは、セット内の要素の存在だけでなく、数も保持するセットです
その中の発生。 JDKでは、Mapコンストラクトでエミュレートできます
<T、Integer>、しかし自然に特殊化されたコレクションを使用すると、使用するコードを大幅に減らすことができます。 比較する
このコレクションのどの実装がさまざまなライブラリを提供していますか:

注意 :テーブルが全体に収まらない場合は、ページをズームアウトするか、別のブラウザーで開いてみてください。
収集タイプグアバApache CommonsコレクションGSコレクションJdk
収集順序が定義されていませんハッシュマルチセット
ハッシュバッグ
ハッシュバッグ
HashMap <文字列、整数>
特定の順序または自然な順序で並べ替えツリーマルチセット
ツリーバッグ
ツリーバッグ
TreeMap <文字列、整数>
追加順にLinkedHashMultiset
--LinkedHashMap <文字列、整数>
マルチスレッドConcurrentHashMultiset
SynchronizedBag
SynchronizedBag
Collections.synchronizedMap(HashMap <文字列、整数>)
マルチスレッドおよびソート-SynchronizedSortedBag
SynchronizedSortedBag
Collections.synchronizedSortedMap(TreeMap <文字列、整数>)
変更不可ImmutableMultiset
変更できないバッグ
変更できないバッグ
Collections.unmodifiableMap(HashMap <文字列、整数>)
可変ではなくソートされていますImmutableSortedMultiset
UnmodifiableSortedBag
UnmodifiableSortedBagCollections.unmodifiableSortedMap(TreeMap <文字列、整数>)


マルチセット(MultiSet / Bag)を使用してテキスト内の単語をカウントする例


タスクがあります :「Hello World! みなさんこんにちは! Hi World!」、それを個別に解析する必要があります
区切り記号がスペースのみの単語。コレクションに保存し、それぞれの出現回数を表示します
単語、テキスト内の単語の合計数、一意の単語の数。

でそれを行う方法を見てみましょう
1.異なるGuisマルチセットオプション:
グアバのHashMultisetを使用して単語をカウントする
System.out.println(multiset)および
System.out.println(multiset.elementSet())-任意、つまり定義されていません。
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset Multiset<String> multiset = HashMultiset.create(Arrays.asList(INPUT_TEXT.split(" "))); //  -   System.out.println(multiset); //  [Hi, Hello x 2, World! x 2, All!] -    //     System.out.println(multiset.elementSet()); //  [Hi, Hello, World!, All!] -    //      System.out.println("Hello = " + multiset.count("Hello")); //  2 System.out.println("World = " + multiset.count("World!")); //  2 System.out.println("All = " + multiset.count("All!")); //  1 System.out.println("Hi = " + multiset.count("Hi")); //  1 System.out.println("Empty = " + multiset.count("Empty")); //  0 //        System.out.println(multiset.size()); // 6 //       System.out.println(multiset.elementSet().size()); // 4 


グアバのTreeMultisetを使用して単語をカウントする
System.out.println(multiset)および
System.out.println(multiset.elementSet())-自然、つまり単語はアルファベット順にソートされます。
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset Multiset<String> multiset = TreeMultiset.create(Arrays.asList(INPUT_TEXT.split(" "))); //  -   System.out.println(multiset); //  [All!, Hello x 2, Hi, World! x 2]-    //     System.out.println(multiset.elementSet()); //  [All!, Hello, Hi, World!]-    //      System.out.println("Hello = " + multiset.count("Hello")); //  2 System.out.println("World = " + multiset.count("World!")); //  2 System.out.println("All = " + multiset.count("All!")); //  1 System.out.println("Hi = " + multiset.count("Hi")); //  1 System.out.println("Empty = " + multiset.count("Empty")); //  0 //        System.out.println(multiset.size()); // 6 //       System.out.println(multiset.elementSet().size()); // 4 


LinkedHashMultisetTest guava
System.out.println(multiset)および
System.out.println(multiset.elementSet())の出力順序は、要素が最初に追加された順序であることに注意してください。
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset Multiset<String> multiset = LinkedHashMultiset.create(Arrays.asList(INPUT_TEXT.split(" "))); //  -   System.out.println(multiset); //  [Hello x 2, World! x 2, All!, Hi]-      //     System.out.println(multiset.elementSet()); //  [Hello, World!, All!, Hi] -      //      System.out.println("Hello = " + multiset.count("Hello")); //  2 System.out.println("World = " + multiset.count("World!")); //  2 System.out.println("All = " + multiset.count("All!")); //  1 System.out.println("Hi = " + multiset.count("Hi")); //  1 System.out.println("Empty = " + multiset.count("Empty")); //  0 //        System.out.println(multiset.size()); // 6 //       System.out.println(multiset.elementSet().size()); // 4 


ConcurrentHashMultiset guava
, System.out.println(multiset)
System.out.println(multiset.elementSet()) — , ,
HashMultiset
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset Multiset<String> multiset = ConcurrentHashMultiset.create(Arrays.asList(INPUT_TEXT.split(" "))); //  -   System.out.println(multiset); //  [Hi, Hello x 2, World! x 2, All!] -    //     System.out.println(multiset.elementSet()); //  [Hi, Hello, World!, All!] -    //      System.out.println("Hello = " + multiset.count("Hello")); //  2 System.out.println("World = " + multiset.count("World!")); //  2 System.out.println("All = " + multiset.count("All!")); //  1 System.out.println("Hi = " + multiset.count("Hi")); //  1 System.out.println("Empty = " + multiset.count("Empty")); //  0 //        System.out.println(multiset.size()); // 6 //       System.out.println(multiset.elementSet().size()); // 4 


2. Bag Apache Commons Collections:
HashBag Apache Commons Collections
, System.out.println(multiset)
System.out.println(multiset.elementSet()) — , .
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset Bag bag = new HashBag(Arrays.asList(INPUT_TEXT.split(" "))); //  -   System.out.println(bag); //  [1:Hi,2:Hello,2:World!,1:All!] -    //     System.out.println(bag.uniqueSet()); //  [Hi, Hello, World!, All!] -    //      System.out.println("Hello = " + bag.getCount("Hello")); //  2 System.out.println("World = " + bag.getCount("World!")); //  2 System.out.println("All = " + bag.getCount("All!")); //  1 System.out.println("Hi = " + bag.getCount("Hi")); //  1 System.out.println("Empty = " + bag.getCount("Empty")); //  0 //        System.out.println(bag.size()); // 6 //       System.out.println(bag.uniqueSet().size()); // 4 


TreeBag Apache Commons Collections
, System.out.println(multiset)
System.out.println(multiset.elementSet()) — , .
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset Bag bag = new TreeBag(Arrays.asList(INPUT_TEXT.split(" "))); //  -   System.out.println(bag); //  [1:All!,2:Hello,1:Hi,2:World!]-    //     System.out.println(bag.uniqueSet()); //  [All!, Hello, Hi, World!]-    //      System.out.println("Hello = " + bag.getCount("Hello")); //  2 System.out.println("World = " + bag.getCount("World!")); //  2 System.out.println("All = " + bag.getCount("All!")); //  1 System.out.println("Hi = " + bag.getCount("Hi")); //  1 System.out.println("Empty = " + bag.getCount("Empty")); //  0 //        System.out.println(bag.size()); // 6 //       System.out.println(bag.uniqueSet().size()); // 4 


SynchronizedBag Apache Commons Collections
, System.out.println(multiset)
System.out.println(multiset.elementSet()) — , ,
HashBag
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset Bag bag = SynchronizedBag.synchronizedBag(new HashBag(Arrays.asList(INPUT_TEXT.split(" ")))); //  -   System.out.println(bag); //  [1:Hi,2:Hello,2:World!,1:All!] -    //     System.out.println(bag.uniqueSet()); //  [Hi, Hello, World!, All!] -    //      System.out.println("Hello = " + bag.getCount("Hello")); //  2 System.out.println("World = " + bag.getCount("World!")); //  2 System.out.println("All = " + bag.getCount("All!")); //  1 System.out.println("Hi = " + bag.getCount("Hi")); //  1 System.out.println("Empty = " + bag.getCount("Empty")); //  0 //        System.out.println(bag.size()); // 6 //       System.out.println(bag.uniqueSet().size()); // 4 


SynchronizedSortedBag Apache Commons Collections
, System.out.println(multiset)
System.out.println(multiset.elementSet()) — , ,
SortedBag
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset Bag bag = SynchronizedSortedBag.synchronizedBag(new TreeBag(Arrays.asList(INPUT_TEXT.split(" ")))); //  -   System.out.println(bag); //  [1:All!,2:Hello,1:Hi,2:World!]-    //     System.out.println(bag.uniqueSet()); //  [All!, Hello, Hi, World!]-    //      System.out.println("Hello = " + bag.getCount("Hello")); //  2 System.out.println("World = " + bag.getCount("World!")); //  2 System.out.println("All = " + bag.getCount("All!")); //  1 System.out.println("Hi = " + bag.getCount("Hi")); //  1 System.out.println("Empty = " + bag.getCount("Empty")); //  0 //        System.out.println(bag.size()); //  6 //       System.out.println(bag.uniqueSet().size()); //  4 


3. Bag GS Collections:
MutableBag GS Collections
, System.out.println(bag) System.out.println(bag.toSet()) —

  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset MutableBag<String> bag = HashBag.newBag(Arrays.asList(INPUT_TEXT.split(" "))); //  -   System.out.println(bag); //  [Hi, World!, World!, Hello, Hello, All!]-    //     System.out.println(bag.toSet()); //  [Hi, Hello, World!, All!] -    //      System.out.println("Hello = " + bag.occurrencesOf("Hello")); //  2 System.out.println("World = " + bag.occurrencesOf("World!")); //  2 System.out.println("All = " + bag.occurrencesOf("All!")); //  1 System.out.println("Hi = " + bag.occurrencesOf("Hi")); //  1 System.out.println("Empty = " + bag.occurrencesOf("Empty")); //  0 //        System.out.println(bag.size()); // 6 //       System.out.println(bag.toSet().size()); // 4 


MutableSortedBag GS Collections
, System.out.println(bag) System.out.println(bag.toSortedSet()) — , ..
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //  Multiset MutableSortedBag<String> bag = TreeBag.newBag(Arrays.asList(INPUT_TEXT.split(" "))); //  -   System.out.println(bag); //  [All!, Hello, Hello, Hi, World!, World!]-    //     System.out.println(bag.toSortedSet()); //  [All!, Hello, Hi, World!]-    //      System.out.println("Hello = " + bag.occurrencesOf("Hello")); //  2 System.out.println("World = " + bag.occurrencesOf("World!")); //  2 System.out.println("All = " + bag.occurrencesOf("All!")); //  1 System.out.println("Hi = " + bag.occurrencesOf("Hi")); //  1 System.out.println("Empty = " + bag.occurrencesOf("Empty")); //  0 //        System.out.println(bag.size()); // 6 //       System.out.println(bag.toSet().size()); // 4 


4. , JDK multiSet HashMap
multiSet HashMap
, , , multiSet
Bag.
  //     String INPUT_TEXT = "Hello World! Hello All! Hi World!"; List<String> listResult = Arrays.asList(INPUT_TEXT.split(" ")); //   Multiset c  HashMap   Map<String, Integer> fakeMultiset = new HashMap<String,Integer>(listResult.size()); for(String word: listResult) { Integer cnt = fakeMultiset.get(word); fakeMultiset.put(word, cnt == null ? 1 : cnt + 1); } //  -   System.out.println(fakeMultiset); //  {World!=2, Hi=1, Hello=2, All!=1}-    //     System.out.println(fakeMultiset.keySet()); //  [World!, Hi, Hello, All!] -    //      System.out.println("Hello = " + fakeMultiset.get("Hello")); //  2 System.out.println("World = " + fakeMultiset.get("World!")); //  2 System.out.println("All = " + fakeMultiset.get("All!")); //  1 System.out.println("Hi = " + fakeMultiset.get("Hi")); //  1 System.out.println("Empty = " + fakeMultiset.get("Empty")); //  null //        Integer cnt = 0; for (Integer wordCount : fakeMultiset.values()){ cnt += wordCount; } System.out.println(cnt); // 6 //      System.out.println(fakeMultiset.size()); // 4 



4.2 Multimap guava, Apache Commons Collections GS Collections



, Multimap map, .
.
, — ,
— , JDK
JDK .

: , .




-
-




-

Guavaアパッチ
Commons
Collections
GS
Collections
JDK

-

HashMapArrayListArrayList-
Multimap
MultiValueMapFastList-
Multimap
HashMap<K,
ArrayList<V>>
いやHashMapHashSetHashMultimapMultiValueMap.
multiValueMap(
new HashMap<K,
Set>(),
HashSet.class);
UnifiedSet-
Multimap
HashMap<K,
HashSet<V>>
-

いやHashMapTreeSetMultimaps.
newMultimap(
HashMap,
Supplier
<TreeSet>)
MultiValueMap.
multiValueMap(
new HashMap<K,
Set>(), TreeSet.class);
TreeSortedSet-
Multimap
HashMap<K,
TreeSet<V>>

-


-

Linked
HashMap
ArrayListLinkedList-
Multimap
MultiValueMap.
multiValueMap(new
LinkedHashMap<K,
List>(), ArrayList.class);
LinkedHashMap<
K, ArrayList<V>>

-


-

いやLinkedHash-
Multimap
Linked-
HashSet
LinkedHash-
Multimap
MultiValueMap.
multiValueMap(new
LinkedHashMap<K, Set>(),
LinkedHashSet.class);
LinkedHashMap<K,
LinkedHashSet<V>>
-

-

いやTreeMapTreeSetTreeMultimapMultiValueMap.
multiValueMap(
new TreeMap<K,
Set>(),TreeSet.class);
TreeMap<K,
TreeSet<V>>

, Apache Commons Collections ,
. guava ,
map' . GS Collections
multimap Bag (HashBagMultimap), . multiset multimap.

Multimap


: «Hello World! Hello All! Hi World!»,
,
, Hello ..


1. Multimap Guava:
HashMultimap guava
, , (
HashMap, HashSet). .
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List <String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap Multimap<String, Integer> multiMap = HashMultimap.create(); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hi=[4], Hello=[0, 2], World!=[1, 5], All!=[3]} -    //     System.out.println(multiMap.keySet()); //  [Hi, Hello, World!, All!] -    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  [] //        System.out.println(multiMap.size()); // 6 //       System.out.println(multiMap.keySet().size()); // 4 


ArrayListMultimapTest guava
, ,
( HashMap, ArrayList).
.
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List <String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap Multimap<String, Integer> multiMap = ArrayListMultimap.create(); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hi=[4], Hello=[0, 2], World!=[1, 5], All!=[3]} -    ,     //     System.out.println(multiMap.keySet()); //  [Hello, World!, All!, Hi]-    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  [] //        System.out.println(multiMap.size()); // 6 //       System.out.println(multiMap.keySet().size()); // 4 


LinkedHashMultimapTest guava
, (
LinkedHashMap, LinkedHashSet).
.
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List <String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap Multimap<String, Integer> multiMap = LinkedHashMultimap.create(); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hello=[0, 2], World!=[1, 5], All!=[3], Hi=[4]}-   //     System.out.println(multiMap.keySet()); //  [Hello, World!, All!, Hi]-    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  [] //        System.out.println(multiMap.size()); // 6 //       System.out.println(multiMap.keySet().size()); // 4 


LinkedListMultimapTest guava
, (
LinkedHashMap, LinkedList).
.
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List <String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap Multimap<String, Integer> multiMap = LinkedListMultimap.create(); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hello=[0, 2], World!=[1, 5], All!=[3], Hi=[4]}-   //     System.out.println(multiMap.keySet()); //  [Hello, World!, All!, Hi]-    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  [] //        System.out.println(multiMap.size()); // 6 //       System.out.println(multiMap.keySet().size()); // 4 


TreeMultimapTest guava
, (
TreeMap, TreeSet).
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List<String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap Multimap<String, Integer> multiMap = TreeMultimap.create(); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hello=[0, 2], World!=[1, 5], All!=[3], Hi=[4]}-   //     System.out.println(multiMap.keySet()); //  [Hello, World!, All!, Hi]-    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  [] //        System.out.println(multiMap.size()); // 6 //       System.out.println(multiMap.keySet().size()); // 4 



2. MultiValueMap Apache Commons Collections:
MultiValueMap Apache Commons Collections
, ( HashMap
ArrayList )
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List<String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap MultiMap<String, Integer> multiMap = new MultiValueMap<String, Integer>(); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hi=[4], Hello=[0, 2], World!=[1, 5], All!=[3]} -    //     System.out.println(multiMap.keySet()); //  [Hi, Hello, World!, All!] -    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  null //       System.out.println(multiMap.keySet().size()); // 4 


MultiValueMap, TreeMap<String, TreeSet>()
,
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List<String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap MultiMap<String, Integer> multiMap = MultiValueMap.multiValueMap(new TreeMap<String, Set>(), TreeSet.class); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {All!=[3], Hello=[0, 2], Hi=[4], World!=[1, 5]} -   //     System.out.println(multiMap.keySet()); //  [All!, Hello, Hi, World!]    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  null //       System.out.println(multiMap.keySet().size()); // 4 


MultiValueMap, LinkedHashMap<String, LinkedHashSet>()
,
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List<String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap MultiMap<String, Integer> multiMap = MultiValueMap.multiValueMap(new LinkedHashMap<String, Set>(), LinkedHashSet.class); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hello=[0, 2], World!=[1, 5], All!=[3], Hi=[4]} -    //     System.out.println(multiMap.keySet()); //  [Hello, World!, All!, Hi] -    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  null //       System.out.println(multiMap.keySet().size()); // 4 


3. Multimap GS Collections:
FastListMultimap
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List<String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap MutableListMultimap<String, Integer> multiMap = new FastListMultimap<String, Integer>(); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hi=[4], World!=[1, 5], Hello=[0, 2], All!=[3]}-    //     System.out.println(multiMap.keysView()); //  [Hi, Hello, World!, All!] -    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  [] //        System.out.println(multiMap.size()); // 6 //        System.out.println(multiMap.keysView().size()); // 4 


HashBagMultimap
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List<String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap MutableBagMultimap<String, Integer> multiMap = new HashBagMultimap<String, Integer>(); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hi=[4], World!=[1, 5], Hello=[0, 2], All!=[3]}-    //     System.out.println(multiMap.keysView()); //  [Hi, Hello, World!, All!] -    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  [] //        System.out.println(multiMap.size()); // 6 //        System.out.println(multiMap.keysView().size()); // 4 


TreeSortedSetMultimap
  String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List<String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap MutableSortedSetMultimap<String, Integer> multiMap = new TreeSortedSetMultimap<String, Integer>(); //  Multimap int i = 0; for(String word: words) { multiMap.put(word, i); i++; } //       System.out.println(multiMap); //  {Hi=[4], World!=[1, 5], Hello=[0, 2], All!=[3]}-    //     System.out.println(multiMap.keysView()); //  [Hi, Hello, World!, All!] -    //        System.out.println("Hello = " + multiMap.get("Hello")); //  [0, 2] System.out.println("World = " + multiMap.get("World!")); //  [1, 5] System.out.println("All = " + multiMap.get("All!")); //  [3] System.out.println("Hi = " + multiMap.get("Hi")); //  [4] System.out.println("Empty = " + multiMap.get("Empty")); //  [] //        System.out.println(multiMap.size()); // 6 //        System.out.println(multiMap.keysView().size()); // 4 



4. , JDK multiMap HashMap
multiMap HashMap
  final int LIST_INDEXES_CAPACITY = 50; String INPUT_TEXT = "Hello World! Hello All! Hi World!"; //       List<String> words = Arrays.asList(INPUT_TEXT.split(" ")); //  Multimap Map<String, List<Integer>> fakeMultiMap = new HashMap<String, List<Integer>>(words.size()); //  map int i = 0; for(String word: words) { List<Integer> indexes = fakeMultiMap.get(word); if(indexes == null) { indexes = new ArrayList<Integer>(LIST_INDEXES_CAPACITY); fakeMultiMap.put(word, indexes); } indexes.add(i); i++; } //       System.out.println(fakeMultiMap); //  {Hi=[4], Hello=[0, 2], World!=[1, 5], All!=[3]} -    //     System.out.println(fakeMultiMap.keySet()); //  [Hi, Hello, World!, All!] -    //        System.out.println("Hello = " + fakeMultiMap.get("Hello")); //  [0, 2] System.out.println("World = " + fakeMultiMap.get("World!")); //  [1, 5] System.out.println("All = " + fakeMultiMap.get("All!")); //  [3] System.out.println("Hi = " + fakeMultiMap.get("Hi")); //  [4] System.out.println("Empty = " + fakeMultiMap.get("Empty")); //  null //        int cnt = 0; for(List<Integer> lists: fakeMultiMap.values()) { cnt += lists.size(); } System.out.println(cnt); // 6 //        System.out.println(fakeMultiMap.keySet().size()); // 4 



4.3 BiMap guava, Apache Commons Collections GS Collections



BiMap , HashBiMap guava GS Collections
BidiMap Apache Commons Collections. HashBiMap, guava Enum
, EnumHashBiMap EnumBiMap, Apache Commons Collections
, .

BiMap - «»,


: ,
- , .


1. BiMap Guava:
BiMap guava
  String[] englishWords = {"one", "two", "three","ball","snow"}; String[] russianWords = {"", "", "","","c"}; //  Multiset BiMap<String, String> biMap = HashBiMap.create(englishWords.length); //  -  int i = 0; for(String englishWord: englishWords) { biMap.put(englishWord, russianWords[i]); i++; } //  -   System.out.println(biMap); //  {two=, three=, snow=c, ball=, one=} -    //     System.out.println(biMap.keySet()); //  [two, three, snow, ball, one] -    System.out.println(biMap.values()); //  [, , c, , ]-    //      System.out.println("one = " + biMap.get("one")); //  one =  System.out.println("two = " + biMap.get("two")); //  two =  System.out.println(" = " + biMap.inverse().get("")); //   = ball System.out.println(" = " + biMap.inverse().get("c")); //   = snow System.out.println("empty = " + biMap.get("empty")); //  empty = null //       System.out.println(biMap.size()); // 5 


EnumBiMap guava
  enum ENGLISH_WORD { ONE, TWO, THREE, BALL, SNOW } enum POLISH_WORD { JEDEN, DWA, TRZY, KULA, SNIEG } //    - ,         public static void main(String[] args) { ENGLISH_WORD[] englishWords = ENGLISH_WORD.values(); POLISH_WORD[] polishWords = POLISH_WORD.values(); //  Multiset BiMap<ENGLISH_WORD, POLISH_WORD> biMap = EnumBiMap.create(ENGLISH_WORD.class, POLISH_WORD.class); //  -  int i = 0; for(ENGLISH_WORD englishWord: englishWords) { biMap.put(englishWord, polishWords[i]); i++; } //  -   System.out.println(biMap); //  {ONE=JEDEN, TWO=DWA, THREE=TRZY, BALL=KULA, SNOW=SNIEG} //     System.out.println(biMap.keySet()); //  [ONE, TWO, THREE, BALL, SNOW] System.out.println(biMap.values()); //  [JEDEN, DWA, TRZY, KULA, SNIEG] //      System.out.println("one = " + biMap.get(ENGLISH_WORD.ONE)); //  one = JEDEN System.out.println("two = " + biMap.get(ENGLISH_WORD.TWO)); //  two = DWA System.out.println("kula = " + biMap.inverse().get(POLISH_WORD.KULA)); //  kula = BALL System.out.println("snieg = " + biMap.inverse().get(POLISH_WORD.SNIEG)); //  snieg = SNOW System.out.println("empty = " + biMap.get("empty")); //  empty = null //       System.out.println(biMap.size()); // 5 } 


EnumHashBiMap guava
  enum ENGLISH_WORD { ONE, TWO, THREE, BALL, SNOW } //    - ,         public static void main(String[] args) { ENGLISH_WORD[] englishWords = ENGLISH_WORD.values(); String[] russianWords = {"", "", "","","c"}; //  Multiset BiMap<ENGLISH_WORD, String> biMap = EnumHashBiMap.create(ENGLISH_WORD.class); //  -  int i = 0; for(ENGLISH_WORD englishWord: englishWords) { biMap.put(englishWord, russianWords[i]); i++; } //  -   System.out.println(biMap); //  {ONE=, TWO=, THREE=, BALL=, SNOW=c} //     System.out.println(biMap.keySet()); //  [ONE, TWO, THREE, BALL, SNOW] System.out.println(biMap.values()); //  [, , , , c] //      System.out.println("one = " + biMap.get(ENGLISH_WORD.ONE)); //  one =  System.out.println("two = " + biMap.get(ENGLISH_WORD.TWO)); //  two =  System.out.println(" = " + biMap.inverse().get("")); //   = BALL System.out.println(" = " + biMap.inverse().get("c")); //   = SNOW System.out.println("empty = " + biMap.get("empty")); //  empty = null //       System.out.println(biMap.size()); // 5 } 


2. C BidiMap Apache Commons Collections:
DualHashBidiMap Apache Commons Collections
  String[] englishWords = {"one", "two", "three","ball","snow"}; String[] russianWords = {"", "", "","","c"}; //  Multiset BidiMap<String, String> biMap = new DualHashBidiMap(); //  -  int i = 0; for(String englishWord: englishWords) { biMap.put(englishWord, russianWords[i]); i++; } //  -   System.out.println(biMap); //  {ball=, snow=c, one=, two=, three=}-    //     System.out.println(biMap.keySet()); //  [ball, snow, one, two, three]-    System.out.println(biMap.values()); //  [, c, , , ]-    //      System.out.println("one = " + biMap.get("one")); //  one =  System.out.println("two = " + biMap.get("two")); //  two =  System.out.println(" = " + biMap.getKey("")); //   = ball System.out.println(" = " + biMap.getKey("c")); //   = snow System.out.println("empty = " + biMap.get("empty")); //  empty = null //       System.out.println(biMap.size()); // 5 


3. C HashBiMap GS Collections:
HashBiMap GS Collections
  String[] englishWords = {"one", "two", "three","ball","snow"}; String[] russianWords = {"", "", "","","c"}; //  Multiset MutableBiMap<String, String> biMap = new HashBiMap(englishWords.length); //  -  int i = 0; for(String englishWord: englishWords) { biMap.put(englishWord, russianWords[i]); i++; } //  -   System.out.println(biMap); //  {two=, ball=, one=, snow=c, three=} -    //     System.out.println(biMap.keySet()); //  [snow, two, one, three, ball] -    System.out.println(biMap.values()); //  [, , , c, ] -    //      System.out.println("one = " + biMap.get("one")); //  one =  System.out.println("two = " + biMap.get("two")); //  two =  System.out.println(" = " + biMap.inverse().get("")); //   = ball System.out.println(" = " + biMap.inverse().get("c")); //   = snow System.out.println("empty = " + biMap.get("empty")); //  empty = null //       System.out.println(biMap.size()); // 5 


4. , JDK
HashMap BiMap
  String[] englishWords = {"one", "two", "three","ball","snow"}; String[] russianWords = {"", "", "","","c"}; //   BiMap Map<String, String> biMapKeys = new HashMap(englishWords.length); Map<String, String> biMapValues = new HashMap(russianWords.length); //  -  int i = 0; for(String englishWord: englishWords) { biMapKeys.put(englishWord, russianWords[i]); biMapValues.put(russianWords[i], englishWord); i++; } //  -   System.out.println(biMapKeys); //  {ball=, two=, three=, snow=c, one=}-    //     System.out.println(biMapKeys.keySet()); //  [ball, two, three, snow, one] -    System.out.println(biMapValues.keySet()); //  [, , , c, ] -    //      System.out.println("one = " + biMapKeys.get("one")); //  one =  System.out.println("two = " + biMapKeys.get("two")); //  two =  System.out.println(" = " + biMapValues.get("")); //   = ball System.out.println(" = " + biMapValues.get("c")); //   = snow System.out.println("empty = " + biMapValues.get("empty")); //  empty = null //       System.out.println(biMapKeys.size()); // 5 



V.


, JDK. , , ( ), , .

5.1 .


Guava gs-collections new, jdk.

5.1.1) (List)
役職JDKguavags-collections
new ArrayList<>()Lists.newArrayList()FastList.newList()
Arrays.asList(«1», «2», «3»)Lists.newArrayList(«1», «2», «3»)FastList.newListWith(«1», «2», «3»)

capacity
new ArrayList<>(100)Lists.newArrayListWithCapacity(100)FastList.newList(100)

new ArrayList<>(collection)Lists.newArrayList(collection)FastList.newList(collection)

Iterable
-Lists.newArrayList(iterable)FastList.newList(iterable)

Iterator'
-Lists.newArrayList(iterator)-
Arrays.asList(array)Lists.newArrayList(array)FastList.newListWith(array)

c
--FastList.newWithNValues(10, () -> «1»)
  //     List<String> emptyGuava = Lists.newArrayList(); // c  guava List<String> emptyJDK = new ArrayList<>(); //  JDK MutableList<String> emptyGS = FastList.newList(); // c  gs //     100  List < String > exactly100 = Lists.newArrayListWithCapacity(100); // c  guava List<String> exactly100JDK = new ArrayList<>(100); //  JDK MutableList<String> empty100GS = FastList.newList(100); // c  gs //       100  (   100) List<String> approx100 = Lists.newArrayListWithExpectedSize(100); // c  guava List<String> approx100JDK = new ArrayList<>(115); //  JDK MutableList<String> approx100GS = FastList.newList(115); // c  gs //      List<String> withElements = Lists.newArrayList("alpha", "beta", "gamma"); // c  guava List<String> withElementsJDK = Arrays.asList("alpha", "beta", "gamma"); //  JDK MutableList<String> withElementsGS = FastList.newListWith("alpha", "beta", "gamma"); // c  gs System.out.println(withElements); System.out.println(withElementsJDK); System.out.println(withElementsGS); //      Iterable  (   ) Collection<String> collection = new HashSet<>(3); collection.add("1"); collection.add("2"); collection.add("3"); List<String> fromIterable = Lists.newArrayList(collection); // c  guava List<String> fromIterableJDK = new ArrayList<>(collection); //  JDK MutableList<String> fromIterableGS = FastList.newList(collection); // c  gs System.out.println(fromIterable); System.out.println(fromIterableJDK); System.out.println(fromIterableGS); /*    JDK   Collection ,  guava  gs  Iterable */ //    Iterator' Iterator<String> iterator = collection.iterator(); List<String> fromIterator = Lists.newArrayList(iterator); // c  guava,   JDK  System.out.println(fromIterator); //     String[] array = {"4", "5", "6"}; List<String> fromArray = Lists.newArrayList(array); // c  guava List<String> fromArrayJDK = Arrays.asList(array); //  JDK MutableList<String> fromArrayGS = FastList.newListWith(array); // c  gs System.out.println(fromArray); System.out.println(fromArrayJDK); System.out.println(fromArrayGS); //    c   MutableList<String> fromFabricGS = FastList.newWithNValues(10, () -> String.valueOf(Math.random())); // c  gs System.out.println(fromFabricGS); 


5.1.2) (set)
役職JDKguavags-collections

new HashSet<>()Sets.newHashSet()UnifiedSet.newSet()

new HashSet<>(Arrays.asList(«alpha», «beta», «gamma»))Sets.newHashSet(«alpha», «beta», «gamma»)UnifiedSet.newSetWith(«alpha», «beta», «gamma»)

new HashSet<>(collection)Sets.newHashSet(collection)UnifiedSet.newSet(collection)

Iterable
-Sets.newHashSet(iterable)UnifiedSet.newSet(iterable)

Iterator'
-Sets.newHashSet(iterator);-

new HashSet<>(Arrays.asList(array))Sets.newHashSet(array)UnifiedSet.newSetWith(array)
  //     Set<String> emptyGuava = Sets.newHashSet(); // c  guava Set<String> emptyJDK = new HashSet<>(); //  JDK Set<String> emptyGS = UnifiedSet.newSet(); // c  gs //       100  (   100) Set<String> approx100 = Sets.newHashSetWithExpectedSize(100); // c  guava Set<String> approx100JDK = new HashSet<>(130); //  JDK Set<String> approx100GS = UnifiedSet.newSet(130); // c  gs //      Set<String> withElements = Sets.newHashSet("alpha", "beta", "gamma"); // c  guava Set<String> withElementsJDK = new HashSet<>(Arrays.asList("alpha", "beta", "gamma")); //  JDK Set<String> withElementsGS = UnifiedSet.newSetWith("alpha", "beta", "gamma"); // c  gs System.out.println(withElements); System.out.println(withElementsJDK); System.out.println(withElementsGS); //      Iterable  (   ) Collection<String> collection = new ArrayList<>(3); collection.add("1"); collection.add("2"); collection.add("3"); Set<String> fromIterable = Sets.newHashSet(collection); // c  guava Set<String> fromIterableJDK = new HashSet<>(collection); //  JDK Set<String> fromIterableGS = UnifiedSet.newSet(collection); // c  gs System.out.println(fromIterable); System.out.println(fromIterableJDK); System.out.println(fromIterableGS); /*    JDK   Collection ,  guava  Iterable */ //    Iterator' Iterator<String> iterator = collection.iterator(); Set<String> fromIterator = Sets.newHashSet(iterator); // c  guava,   JDK  System.out.println(fromIterator); //     String[] array = {"4", "5", "6"}; Set<String> fromArray = Sets.newHashSet(array); // c  guava Set<String> fromArrayJDK = new HashSet<>(Arrays.asList(array)); //  JDK Set<String> fromArrayGS = UnifiedSet.newSetWith(array); // c  gs System.out.println(fromArray); System.out.println(fromArrayJDK); System.out.println(fromArrayGS); 


5.1.3) Map
役職JDKguavags-collections
map'new HashMap<>()Maps.newHashMap()UnifiedMap.newMap()
map' c
capacity
new HashMap<>(130)Maps.newHashMapWithExpectedSize(100)UnifiedMap.newMap(130)
map' map'new HashMap<>(map)Maps.newHashMap(map)UnifiedMap.newMap(map)
map'--UnifiedMap.newWithKeysValues(«1», «a», «2», «b»)
map
//
Map<String, String> emptyGuava = Maps.newHashMap(); // c guava
Map<String, String> emptyJDK = new HashMap<>(); // JDK
Map<String, String> emptyGS = UnifiedMap.newMap(); // c gs

// map' 100 ( 100)
Map<String, String> approx100 = Maps.newHashMapWithExpectedSize(100); // c guava
Map<String, String> approx100JDK = new HashMap<>(130); // JDK
Map<String, String> approx100GS = UnifiedMap.newMap(130); // c gs

// map' map'
Map<String, String> map = new HashMap<>(3);
map.put(«k1»,«v1»);
map.put(«k2»,«v2»);
Map<String, String> withMap = Maps.newHashMap(map); // c guava
Map<String, String> withMapJDK = new HashMap<>(map); // JDK
Map<String, String> withMapGS = UnifiedMap.newMap(map); // c gs

System.out.println(withMap);
System.out.println(withMapJDK);
System.out.println(withMapGS);

// map'
Map<String, String> withKeys = UnifiedMap.newWithKeysValues(«1», «a», «2», «b»);
System.out.println(withKeys);


5.2 .



役職JDKguavaapachegs-collections
Collections.frequency(collection, «1»)Iterables.frequency(iterable, «1»)CollectionUtils.cardinality(«1», iterable)mutableCollection.count((each) -> «a1».equals(each))
collection.stream().findFirst().orElse(«1»)Iterables.getFirst(iterable, «1»)CollectionUtils.get(iterable, 0)orderedIterable.getFirst()
collection.stream().skip(collection.size()-1).findFirst().orElse(«1»);Iterables.getLast(iterable, «1»)CollectionUtils.get(collection, collection.size()-1)orderedIterable.getLast()
Collections.max(collection)Ordering.natural().max(iterable)-orderedIterable.max()
Collections.min(collection)Ordering.natural().min(iterable)-orderedIterable.min()
Iterables.getOnlyElement(iterable)CollectionUtils.extractSingleton(collection)
Collections.binarySearch(list, «13»)Ordering.natural().binarySearch(list, «13»)mutableList.binarySearch(«13»)
collection.stream().filter(«13»::equals).findFirst().get()Iterables.find(iterable, «13»::equals)CollectionUtils.find(iterable, «13»::equals)mutableList.select(«13»::equals).get(0)
collection.stream().filter((s) -> s.contains(«1»)).collect(Collectors.toList())Iterables.filter(iterable, (s) -> s.contains(«1»))CollectionUtils.select(iterable, (s) -> s.contains(«1»))mutableCollection.select((s) -> s.contains(«1»))
, : collection — Collection, iterable — Iterable, list — List, orderedIterable mutableList GS (orderedIterable — , mutableList — )

:
1)
  Collection<String> collection = Lists.newArrayList("a1", "a2", "a3", "a1"); Iterable<String> iterable = collection; MutableCollection<String> collectionGS = FastList.newListWith("a1", "a2", "a3", "a1"); //     int i1 = Iterables.frequency(iterable, "a1"); //   guava int i2 = Collections.frequency(collection, "a1"); // c  JDK int i3 = CollectionUtils.cardinality("a1", iterable); // c  Apache int i4 = collectionGS.count((s) -> "a1".equals(s)); long i5 = collection.stream().filter((s) -> "a1".equals(s)).count(); // c  stream JDK System.out.println("count = " + i1 + ":" + i2 + ":" + i3 + ":" + i4 + ":" + i5); //  count = 2:2:2:2:2 

2)
  Collection<String> collection = Lists.newArrayList("a1", "a2", "a3", "a1"); OrderedIterable<String> orderedIterable = FastList.newListWith("a1", "a2", "a3", "a1"); Iterable<String> iterable = collection; //     Iterator<String> iterator = collection.iterator(); // c  JDK String jdk = iterator.hasNext() ? iterator.next(): "1"; String guava = Iterables.getFirst(iterable, "1"); //   guava String apache = CollectionUtils.get(iterable, 0); // c  Apache String gs = orderedIterable.getFirst(); // c  GS String stream = collection.stream().findFirst().orElse("1"); // c  Stream API System.out.println("first = " + jdk + ":" + guava + ":" + apache + ":" + gs + ":" + stream); //  first = a1:a1:a1:a1:a1 

3)
  Collection<String> collection = Lists.newArrayList("a1", "a2", "a3", "a8"); OrderedIterable<String> orderedIterable = FastList.newListWith("a1", "a2", "a3", "a8"); Iterable<String> iterable = collection; //     Iterator<String> iterator = collection.iterator(); // c  JDK String jdk = "1"; while(iterator.hasNext()) { jdk = iterator.next(); } String guava = Iterables.getLast(iterable, "1"); //   guava String apache = CollectionUtils.get(collection, collection.size()-1); // c  Apache String gs = orderedIterable.getLast(); // c  GS String stream = collection.stream().skip(collection.size()-1).findFirst().orElse("1"); // c  Stream API System.out.println("last = " + jdk + ":" + guava + ":" + apache + ":" + gs + ":" + stream); //  last = a8:a8:a8:a8:a8 

4)
  Collection<String> collection = Lists.newArrayList("5", "1", "3", "8", "4"); OrderedIterable<String> orderedIterable = FastList.newListWith("5", "1", "3", "8", "4"); Iterable<String> iterable = collection; //     String jdk = Collections.max(collection); // c  JDK String gs = orderedIterable.max(); // c  GS String guava = Ordering.natural().max(iterable); //   guava System.out.println("max = " + jdk + ":" + guava + ":" + gs); //  max = 8:8:8 

5)
  Collection<String> collection = Lists.newArrayList("5", "1", "3", "8", "4"); OrderedIterable<String> orderedIterable = FastList.newListWith("5", "1", "3", "8", "4"); Iterable<String> iterable = collection; //     String jdk = Collections.min(collection); // c  JDK String gs = orderedIterable.min(); // c  GS String guava = Ordering.natural().min(iterable); //   guava System.out.println("min = " + jdk + ":" + guava + ":" + gs); //  min = 1:1:1 

6)
  Collection<String> collection = Lists.newArrayList("a3"); OrderedIterable<String> orderedIterable = FastList.newListWith("a3"); Iterable<String> iterable = collection; //     String guava = Iterables.getOnlyElement(iterable); //   guava String jdk = collection.iterator().next(); // c  JDK String apache = CollectionUtils.extractSingleton(collection); // c  Apache assert(orderedIterable.size() > 1);// c  GS String gs = orderedIterable.getFirst(); System.out.println("single = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  single = a3:a3:a3:a3 

7)
  List<String> list = Lists.newArrayList("2", "4", "13", "31", "43"); MutableList<String> mutableList = FastList.newListWith("2", "4","13", "31", "43"); //      int jdk = Collections.binarySearch(list, "13"); int guava = Ordering.natural().binarySearch(list, "13"); int gs = mutableList.binarySearch("13"); System.out.println("find = " + jdk + ":" + guava + ":" + gs); //  find = 2:2:2 
8)
  Collection<String> collection = Lists.newArrayList("a1", "a2", "a3", "a1"); MutableCollection<String> orderedIterable = FastList.newListWith("a1", "a2", "a3", "a1"); Iterable<String> iterable = collection; //       String jdk = collection.stream().skip(2).findFirst().get(); // c  JDK String guava = Iterables.get(iterable, 2); //   guava String apache = CollectionUtils.get(iterable, 2); // c  Apache System.out.println("third = " + jdk + ":" + guava + ":" + apache); //  third = a3:a3:a3 
9)
  Collection<String> collection = Lists.newArrayList("2", "14", "3", "13", "43"); MutableCollection<String> mutableCollection = FastList.newListWith("2", "14", "3", "13", "43"); Iterable<String> iterable = collection; //      List<String> jdk = collection.stream().filter((s) -> s.contains("1")).collect(Collectors.toList()); // c  JDK Iterable<String> guava = Iterables.filter(iterable, (s) -> s.contains("1")); //   guava Collection<String> apache = CollectionUtils.select(iterable, (s) -> s.contains("1")); // c  Apache MutableCollection<String> gs = mutableCollection.select((s) -> s.contains("1")); // c  GS System.out.println("select = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  select = [14, 13]:[14, 13]:[14, 13]:[14, 13] 



5.3 ,


役職JDKguavaapachegs-collections
collection1.containsAll(collection2)Iterables.elementsEqual(iterable1, iterable2)CollectionUtils.containsAll(collection1, collection2)mutableCollection1.containsAll(mutableCollection2)
!Collections.disjoint(collection1, collection2)!Sets.intersection(set1, set2).isEmpty()CollectionUtils.containsAny(collection1, collection2)!mutableSet1.intersect(mutableSet2).isEmpty()
()Set<T> result = new HashSet<>(set1);
result.retainAll(set2)
Sets.intersection(set1, set2)CollectionUtils.intersection(collection1, collection2)mutableSet1.intersect(mutableSet2)
Collections.disjoint(collection1, collection2)Sets.intersection(set1, set2).isEmpty()!CollectionUtils.containsAny(collection1, collection2)mutableSet1.intersect(mutableSet2).isEmpty()
, (difference)Set<T> result = new HashSet<>(set1);
result.removeAll(set2)
Sets.difference(set1, set2)CollectionUtils.removeAll(collection1, collection2)mutableSet1.difference(mutableSet2)
(symmetric difference)Sets.symmetricDifference(set1, set2)CollectionUtils.disjunction(collection1, collection2)mutableSet1.symmetricDifference(mutableSet2)
Set<T> result = new HashSet<>(set1);
result.addAll(set2)
Sets.union(set1, set2)CollectionUtils.union(collection1, collection2)mutableSet1.union(mutableSet2)

:
1)
  Collection<String> collection1 = Lists.newArrayList("a1", "a2", "a3", "a1"); Collection<String> collection2 = Lists.newArrayList("a1", "a2", "a3", "a1"); Iterable<String> iterable1 = collection1; Iterable<String> iterable2 = collection2; MutableCollection<String> mutableCollection1 = FastList.newListWith("a1", "a2", "a3", "a1"); MutableCollection<String> mutableCollection2 = FastList.newListWith("a1", "a2", "a3", "a1"); //      boolean jdk = collection1.containsAll(collection2); // c  JDK boolean guava = Iterables.elementsEqual(iterable1, iterable2); //   guava boolean apache = CollectionUtils.containsAll(collection1, collection2); // c  Apache boolean gs = mutableCollection1.containsAll(mutableCollection2); // c  GS System.out.println("containsAll = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  containsAll = true:true:true:true 

2)
  Collection<String> collection1 = Lists.newArrayList("a1", "a2", "a3", "a1"); Collection<String> collection2 = Lists.newArrayList("a4", "a8", "a3", "a5"); Set<String> set1 = Sets.newHashSet("a1", "a2", "a3", "a1"); Set<String> set2 = Sets.newHashSet("a4", "a8", "a3", "a5"); MutableSet<String> mutableSet1 = UnifiedSet.newSetWith("a1", "a2", "a3", "a1"); MutableSet<String> mutableSet2 = UnifiedSet.newSetWith("a4", "a8", "a3", "a5"); //           boolean jdk = !Collections.disjoint(collection1, collection2); // c  JDK boolean guava = !Sets.intersection(set1, set2).isEmpty(); //   guava boolean apache = CollectionUtils.containsAny(collection1, collection2); // c  Apache boolean gs = !mutableSet1.intersect(mutableSet2).isEmpty(); // c  GS System.out.println("containsAny = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  containsAny = true:true:true:true 

3) ()
  Collection<String> collection1 = Lists.newArrayList("a1", "a2", "a3", "a1"); Collection<String> collection2 = Lists.newArrayList("a4", "a8", "a3", "a5"); Set<String> set1 = Sets.newHashSet("a1", "a2", "a3", "a1"); Set<String> set2 = Sets.newHashSet("a4", "a8", "a3", "a5"); MutableSet<String> mutableSet1 = UnifiedSet.newSetWith("a1", "a2", "a3", "a1"); MutableSet<String> mutableSet2 = UnifiedSet.newSetWith("a4", "a8", "a3", "a5"); //        Set<String> jdk = new HashSet<>(set1); // c  JDK jdk.retainAll(set2); Set<String> guava = Sets.intersection(set1, set2); //   guava Collection<String> apache = CollectionUtils.intersection(collection1, collection2); // c  Apache Set<String> gs = mutableSet1.intersect(mutableSet2); // c  GS System.out.println("intersect = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  intersect = [a3]:[a3]:[a3]:[a3] 

4) , (difference)
  Collection<String> collection1 = Lists.newArrayList("a2", "a3"); Collection<String> collection2 = Lists.newArrayList("a8", "a3", "a5"); Set<String> set1 = Sets.newHashSet("a2", "a3"); Set<String> set2 = Sets.newHashSet("a8", "a3", "a5"); MutableSet<String> mutableSet1 = UnifiedSet.newSetWith("a2", "a3"); MutableSet<String> mutableSet2 = UnifiedSet.newSetWith("a8", "a3", "a5"); //   ,          (difference) Set<String> jdk = new HashSet<>(set1); // c  JDK jdk.removeAll(set2); Set<String> guava = Sets.difference(set1, set2); //   guava Collection<String> apache = CollectionUtils.removeAll(collection1, collection2); // c  Apache Set<String> gs = mutableSet1.difference(mutableSet2); // c  GS System.out.println("difference = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  difference = [a2]:[a2]:[a2]:[a2] 

5) (symmetric difference)
  Collection<String> collection1 = Lists.newArrayList("a2", "a3"); Collection<String> collection2 = Lists.newArrayList("a8", "a3", "a5"); Set<String> set1 = Sets.newHashSet("a2", "a3"); Set<String> set2 = Sets.newHashSet("a8", "a3", "a5"); MutableSet<String> mutableSet1 = UnifiedSet.newSetWith("a2", "a3"); MutableSet<String> mutableSet2 = UnifiedSet.newSetWith("a8", "a3", "a5"); //     (symmetric difference)    Set<String> intersect = new HashSet<>(set1); // c  JDK intersect.retainAll(set2); Set<String> jdk = new HashSet<>(set1); jdk.addAll(set2); jdk.removeAll(intersect); Set<String> guava = Sets.symmetricDifference(set1, set2); //   guava Collection<String> apache = CollectionUtils.disjunction(collection1, collection2); // c  Apache Set<String> gs = mutableSet1.symmetricDifference(mutableSet2); // c  GS System.out.println("symmetricDifference = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  symmetricDifference = [a2, a5, a8]:[a2, a5, a8]:[a2, a5, a8]:[a2, a5, a8] 

6)
  Set<String> set1 = Sets.newHashSet("a1", "a2"); Set<String> set2 = Sets.newHashSet("a4"); MutableSet<String> mutableSet1 = UnifiedSet.newSetWith("a1", "a2"); MutableSet<String> mutableSet2 = UnifiedSet.newSetWith("a4"); Collection<String> collection1 = set1; Collection<String> collection2 = set2; //     Set<String> jdk = new HashSet<>(set1); // c  JDK jdk.addAll(set2); Set<String> guava = Sets.union(set1, set2); //   guava Collection<String> apache = CollectionUtils.union(collection1, collection2); // c  Apache Set<String> gs = mutableSet1.union(mutableSet2); // c  GS System.out.println("union = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  union = [a1, a2, a4]:[a1, a2, a4]:[a1, a2, a4]:[a1, a2, a4] 



5.4


役職JDKguavaapachegs-collections
Collections.sort(list);Ordering.natural().sortedCopy(iterable)mutableList.sortThis()
collection.removeIf((s) -> s.contains(«1»))Iterables.removeIf(iterable, (s) -> s.contains(«1»))CollectionUtils.filter(iterable, (s) -> !s.contains(«1»))mutableCollection.removeIf((Predicate<String>) (s) -> s.contains(«1»))
collection.removeIf((s) -> !s.contains(«1»))Iterables.removeIf(iterable, (s) -> !s.contains(«1»))CollectionUtils.filter(iterable, (s) -> s.contains(«1»))mutableCollection.removeIf((Predicate<String>) (s) -> !s.contains(«1»))
collection.stream().map((s) -> s + "_1").collect(Collectors.toList())Iterables.transform(iterable, (s) -> s + "_1")CollectionUtils.transform(collection, (s) -> s + "_1")mutableCollection.collect((s) -> s + "_1")
collection.stream().forEach((s) -> s.append("_1"))Iterables.transform(iterable, (s) -> s.append("_1"))CollectionUtils.transform(collection, (s) -> s.append("_1"))mutableCollection.forEach((Procedure<StringBuilder>) (s) -> s.append("_1"))

1)
  List<String> jdk = Lists.newArrayList("a1", "a2", "a3", "a1"); Iterable<String> iterable = jdk; MutableList<String> gs = FastList.newList(jdk); //   Collections.sort(jdk); //   jdk List<String> guava = Ordering.natural().sortedCopy(iterable); //   guava gs.sortThis(); // c  gs System.out.println("sort = " + jdk + ":" + guava + ":" + gs); //  sort = [a1, a1, a2, a3]:[a1, a1, a2, a3]:[a1, a1, a2, a3] 

2)
  Collection<String> jdk = Lists.newArrayList("a1", "a2", "a3", "a1"); Iterable<String> guava = Lists.newArrayList(jdk); Iterable<String> apache = Lists.newArrayList(jdk); MutableCollection<String> gs = FastList.newList(jdk); //      jdk.removeIf((s) -> s.contains("1")); //   jdk Iterables.removeIf(guava, (s) -> s.contains("1")); //   guava CollectionUtils.filter(apache, (s) -> !s.contains("1")); //   apache gs.removeIf((Predicate<String>) (s) -> s.contains("1")); // c  gs System.out.println("removeIf = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  removeIf = [a2, a3]:[a2, a3]:[a2, a3]:[a2, a3] 

3)
  Collection<String> jdk = Lists.newArrayList("a1", "a2", "a3", "a1"); Iterable<String> guava = Lists.newArrayList(jdk); Iterable<String> apache = Lists.newArrayList(jdk); MutableCollection<String> gs = FastList.newList(jdk); //       jdk.removeIf((s) -> !s.contains("1")); //   jdk Iterables.removeIf(guava, (s) -> !s.contains("1")); //   guava CollectionUtils.filter(apache, (s) -> s.contains("1")); //   apache gs.removeIf((Predicate<String>) (s) -> !s.contains("1")); // c  gs System.out.println("retainIf = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  retainIf = [a1, a1]:[a1, a1]:[a1, a1]:[a1, a1] 

4)
  Collection<String> collection = Lists.newArrayList("a1", "a2", "a3", "a1"); Iterable<String> iterable = collection; Collection<String> apache = Lists.newArrayList(collection); MutableCollection<String> mutableCollection = FastList.newList(collection); //        List<String> jdk = collection.stream().map((s) -> s + "_1").collect(Collectors.toList()); //   jdk Iterable<String> guava = Iterables.transform(iterable, (s) -> s + "_1"); //   guava CollectionUtils.transform(apache, (s) -> s + "_1"); //   apache MutableCollection<String> gs = mutableCollection.collect((s) -> s + "_1"); // c  gs System.out.println("transform = " + jdk + ":" + guava + ":" + apache + ":" + gs); //  transform = [a1_1, a2_1, a3_1, a1_1]:[a1_1, a2_1, a3_1, a1_1]:[a1_1, a2_1, a3_1, a1_1]:[a1_1, a2_1, a3_1, a1_1] 

5)
  Collection<StringBuilder> jdk = Lists.newArrayList(new StringBuilder("a1"), new StringBuilder("a2"), new StringBuilder("a3")); Iterable<StringBuilder> iterable = Lists.newArrayList(new StringBuilder("a1"), new StringBuilder("a2"), new StringBuilder("a3"));; Collection<StringBuilder> apache = Lists.newArrayList(new StringBuilder("a1"), new StringBuilder("a2"), new StringBuilder("a3")); MutableCollection<StringBuilder> gs = FastList.newListWith(new StringBuilder("a1"), new StringBuilder("a2"), new StringBuilder("a3")); //      jdk.stream().forEach((s) -> s.append("_1")); //   jdk Iterable<StringBuilder> guava = Iterables.transform(iterable, (s) -> s.append("_1")); //   guava CollectionUtils.transform(apache, (s) -> s.append("_1")); //   apache gs.forEach((Procedure<StringBuilder>) (s) -> s.append("_1")); // c  gs System.out.println("change = " + jdk + ":" + guava + ":" + apache + ":" + gs); // changeAll = [a1_1, a2_1, a3_1]:[a1_1, a2_1, a3_1]:[a1_1, a2_1, a3_1]:[a1_1, a2_1, a3_1] 



VI.



5.1


( Java, ):
1) () — , ,
— ,
— , ,
— ,
, ,

,
2) (Stack) — , «LIFO» (« — »).
, /.
3) (Queue) — , «FIFO» (« — »).
/.
4) (Double-ended queue) — ,
.
5) (. priority queue) — ,
. ,
(heap) — , ,
6) (), (Associative array, Dictionary) — ,
«— »
- (hashtable) — , ,
- (Multimap multihash) — -,
,
- - (bi-map) — -,
, ,
- (hashtable) — -, ,
- (hashtable) — -, ,
7) — ,
,
— , ,
,
— , , ,
— , , ,
8) — 1 0,
9)
,
10) — , ,
11) — ,

Java :

: , .
役職ListSetMapQuery
Dequery
.. JDK
guavaapachegs-collections
1) ()
ArrayListLinkedHashSetLinkedHashMapArrayDequeTreeListFastList
LinkedListLinkedHashSetLinkedHashMapLinkedListNodeCachingLinkedList
2) (Stack)LinkedListArrayDequeArrayStack
3) (Queue)LinkedListArrayDequeCircularFifoQueue
4) LinkedListArrayDeque
5)
(heap)
PriorityQueue
6) ()HashMapHashedMapUnifiedMap
- (hashtable)HashSetHashMapHashedMapUnifiedMap
-MultimapMultiMapMultimap
- -HashBiMapBidiMapHashBiMap
-LinkedHashSetLinkedHashMapLinkedMap
-TreeSetTreeMapPatriciaTrieTreeSortedMap
7) HashSetUnifiedSet
HashMultisetHashBagHashBag
LinkedHashSet
TreeSetPatriciaTrieTreeSortedSet
8) BitSet
9) RangeSet
RangeMap
10) TreeSetTreeMapPatriciaTrieTreeSortedSet
11) LinkedHashMap
WeakHashMap
LoadingCache


VII. おわりに



, , , . , ( ) , - .

github' .

, :
1. java.util.concurrent.* tutorial
2. Trove library: using primitive collections for performance
3. Java performance tuning tips
4. Large HashMap overview
5. Memory consumption of popular Java data types
6. , , , javadoc

PPS opensource [useful-java-links](https://github.com/Vedenin/useful-java-links/tree/master/link-rus) — , Java , . [ ](https://github.com/Vedenin/useful-java-links/) opensource [Hello world](https://github.com/Vedenin/useful-java-links/tree/master/helloworlds) Java maven ( ).

Source: https://habr.com/ru/post/J256877/


All Articles