[解決済み] なぜJavaにはSortedListがないのですか?
質問
Javaでは
SortedSet
と
SortedMap
というインターフェイスがあります。どちらも
Java Collections フレームワーク
で、要素にアクセスするためのソートされた方法を提供します。
しかし、私の理解では
SortedList
をJavaで作成します。使用できるのは
java.util.Collections.sort()
でリストを並べ替えることができます。
なぜそのようなデザインになっているのか、何か思い当たることはありますか?
解決方法は?
リストのイテレータは、何よりもまず、リストの要素をリストの内部順序で取得することを保証します(別名. 挿入順 ). 具体的には、要素を挿入した順、あるいはリストをどのように操作したかによります。ソートはデータ構造の操作とみなすことができ、リストのソートにはいくつかの方法があります。
の順に方法を並べることにします。 有用性 個人的に見た場合
1. の使用を検討する。
Set
または
Bag
コレクションに置き換えます。
NOTE このオプションを一番上に置いたのは、とにかく普通はこうしたいからです。
ソートされたセット 挿入時に自動的にコレクションをソートする つまり、コレクションに要素を追加している間に並べ替えが行われます。また、手動でソートする必要がないことも意味しています。
さらに、要素の重複を気にする必要がない(あるいはある)ことが確実な場合には
TreeSet<T>
代わりに これは
SortedSet
と
NavigableSet
というインターフェイスを持ち、リストで期待されるような動作をします。
TreeSet<String> set = new TreeSet<String>();
set.add("lol");
set.add("cat");
// automatically sorts natural order when adding
for (String s : set) {
System.out.println(s);
}
// Prints out "cat" and "lol"
もし自然な並び順を望まない場合は、コンストラクタのパラメータに
Comparator<T>
.
または
マルチセット
(として知られている)。
バッグ
)
というのは
Set
は、代わりに要素の重複を許容するもので、サードパーティによる実装もあります。最も顕著なのは
グアバライブラリ
があります。
TreeMultiset
と同じように動作します。
TreeSet
.
2. でリストをソートします。
Collections.sort()
前述したように、ソートの
List
は、データ構造の操作になります。したがって、さまざまな方法でソートされる1つの真実のソースが必要な場合は、手動でソートするのがよいでしょう。
でリストをソートすることができます。
java.util.Collections.sort()
メソッドを使用します。以下は、そのコード例です。
List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");
Collections.sort(strings);
for (String s : strings) {
System.out.println(s);
}
// Prints out "cat" and "lol"
コンパレータの使用
明確な利点は
Comparator
の中に
sort
メソッドを使用します。また、Java では、このメソッドに対応するいくつかの実装が用意されています。
Comparator
のような
Collator
これは、ロケールを考慮したソート文字列に有効です。以下はその一例である。
Collator usCollator = Collator.getInstance(Locale.US);
usCollator.setStrength(Collator.PRIMARY); // ignores casing
Collections.sort(strings, usCollator);
同時並行環境での並べ替え
ただし
sort
なぜなら、コレクションのインスタンスが操作されるからです。そして、代わりに不変のコレクションを使用することを考慮すべきです。これは、Guavaが
Ordering
クラスで、シンプルなワンライナーです。
List<string> sorted = Ordering.natural().sortedCopy(strings);
3. リストを
java.util.PriorityQueue
Javaにはソートされたリストはありませんが、ソートされたキューがあり、おそらくあなたにとって同様に機能するでしょう。それは
java.util.PriorityQueue
クラスがあります。
Nico Haaseがコメントでリンクしているのは 関連質問 にも答えています。
ソートされたコレクションで を操作したいとは思わないでしょう。 PriorityQueue が List インターフェイスを実装しないのは、その要素に直接アクセスできるようになるためです。
の注意点
PriorityQueue
イテレータ
は
PriorityQueue
クラスは
Iterable<E>
と
Collection<E>
インターフェイスを持つので、通常通り反復処理することができます。しかし、イテレータはソートされた順番に要素を返すことを保証していない。その代わり(Alderathがコメントで指摘しているように)、次のようなことが必要です。
poll()
を空にするまで待ち行列に入れます。
なお、リストを優先キューに変換する場合は コンストラクタは、任意のコレクション :
List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");
PriorityQueue<String> sortedStrings = new PriorityQueue(strings);
while(!sortedStrings.isEmpty()) {
System.out.println(sortedStrings.poll());
}
// Prints out "cat" and "lol"
4. 自分で書く
SortedList
クラス
NOTE こんなことしちゃダメだよ。
新しい要素を追加するたびにソートする独自の List クラスを書くことができます。これは、実装によってはかなり計算が重くなります。 であり、無意味である というのも、主に2つの理由があるからです。
-
という契約を破ることになります。
List<E>
インターフェイスが持つadd
メソッドは、ユーザーが指定したインデックスに要素が存在することを保証する必要があります。 - なぜ車輪の再発明をするのか?上記の最初のポイントで指摘したように、代わりにTreeSetまたはMultisetsを使用すべきです。
しかし、練習としてやってみたいということであれば、以下のコードサンプルを参考にしてください。
AbstractList
抽象クラスです。
public class SortedList<E> extends AbstractList<E> {
private ArrayList<E> internalList = new ArrayList<E>();
// Note that add(E e) in AbstractList is calling this one
@Override
public void add(int position, E e) {
internalList.add(e);
Collections.sort(internalList, null);
}
@Override
public E get(int i) {
return internalList.get(i);
}
@Override
public int size() {
return internalList.size();
}
}
必要なメソッドをオーバーライドしていない場合、デフォルトの実装は
AbstractList
を投げます。
UnsupportedOperationException
s.
関連
-
スタイルが読み込まれず、ブラウザコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
Java のエラーです。未解決のコンパイル問題 解決方法
-
SocketTimeoutExceptionです。読み込みがタイムアウトしました
-
[解決済み] この2回(1927年)を引き算すると、なぜおかしな結果になるのでしょうか?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み】なぜJavaの+=, -=, *=, /=複合代入演算子はキャスティングを必要としないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
スタイルが読み込まれず、ブラウザコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
java の例外が発生しました java
-
IllegalArgumentException この例外を解決する方法
-
Dateが型に解決できない問題を解決する
-
JavaMailのメール送信が失敗するケースとその説明の分析
-
mavenプロジェクトのテストエラー java.lang.ClassNotFoundException: org.glassfish.jersey.client.ClientConfig の問題を解決する。
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
SocketTimeoutExceptionです。読み込みがタイムアウトしました
-
java -serverコマンドで「Error: no `server' JVM at ... jvm.dll」を解決する方法です。
-
このラインで複数のマーカーを解決する方法