web-dev-qa-db-ja.com

ハッシュセットをソートする方法

リストには、Collections.sort(List)メソッドを使います。 HashSetをソートしたい場合はどうなりますか?

79
Diana

HashSetはその要素の順序を保証しません。この保証が必要な場合は、TreeSetを使用して要素を保持することを検討してください。

ただし、この1回の発生に合わせて要素を並べ替えるだけの場合は、一時的にListを作成して並べ替えます。

Set<?> yourHashSet = new HashSet<>();

...

List<?> sortedList = new ArrayList<>(yourHashSet);
Collections.sort(sortedList);
96
isak gilbert

すべてのオブジェクトを TreeSet に追加すると、ソートセットが得られます。下記は生の例です。

HashSet myHashSet = new HashSet();
myHashSet.add(1);
myHashSet.add(23);
myHashSet.add(45);
myHashSet.add(12);

TreeSet myTreeSet = new TreeSet();
myTreeSet.addAll(myHashSet);
System.out.println(myTreeSet); // Prints [1, 12, 23, 45]
56
Abdullah Khan

実際のオブジェクトとしてJava.util.TreeSetを使用してください。このコレクションを反復処理すると、値は明確に定義された順序で返されます。

あなたがJava.util.HashSetを使うならば、その順序は(内容に基づいて)ほとんど確実に辞書式ではない内部ハッシュ関数に依存します。

14
P45 Imminent

代わりに TreeSet を使うことができます。

11
jcarvalho

Java 8のソート方法は次のとおりです。

fooHashSet.stream()
  .sorted(Comparator.comparing(Foo::getSize)) //comparator - how you want to sort it
  .collect(Collectors.toList()); //collector - what you want to collect it to

* Foo::getSizeはYourItemのHashSetをサイズで自然にソートする方法の一例です。

* Collectors.toList()はソートの結果をListに集めようとしているので、あなたはそれをList<Foo> sortedListOfFoo =で捕らえる必要があるでしょう。

11
LazerBanana

Java 8コレクターとTreeSetを使用できます

list.stream().collect(Collectors.toCollection(TreeSet::new))

5
Ninja

他の回答で述べたようにTreeSetを使うことができます。

使い方をもう少し詳しく説明します。

TreeSet<String> ts = new TreeSet<String>();
ts.add("b1");
ts.add("b3");
ts.add("b2");
ts.add("a1");
ts.add("a2");
System.out.println(ts);
for (String s: ts)
    System.out.println(s);

出力:

[a1, a2, a3, a4, a5]
a1
a2
b1
b2
b3
4
Alisa

HashSet内の要素はソートできません。 HashSetに要素を入れるたびに、バケツ全体がめちゃくちゃになります。それについての良いところはパフォーマンスの効率です。

TreeSetは、要素を挿入するたびにすべての要素を自動的に並べ替えます。

おそらく、あなたがやろうとしているのは一度だけソートすることです。その場合、TreeSetは常に新しい追加要素の配置を決定する必要があるため、最適な選択肢ではありません。

最も効率的な解決策は、ArrayListを使用することです。新しいリストを作成し、すべての要素を追加してからそれを1回ソートします。一意の要素のみを保持したい場合(set doのようにすべての重複を削除してからLinkedHashSetにリストを追加しても、既にソートされた順序が保持されます)

List<Integer> list = new ArrayList<>();
list.add(6);
list.add(4);
list.add(4);
list.add(5);
Collections.sort(list);
Set<Integer> unique = new LinkedHashSet<>(list); // 4 5 6
// The above line is not copying the objects! It only copies references.

これで、リスト形式にしたい場合はソートセットを入手してからリストに変換します。

2
off99555
1. Add all set element in list -> al.addAll(s);
2. Sort all the elements in list using -> Collections.sort(al);


 public class SortSetProblem {
 public static void main(String[] args) {
    ArrayList<String> al = new ArrayList();
    Set<String> s = new HashSet<>();
    s.add("ved");
    s.add("prakash");
    s.add("sharma");
    s.add("Apple");
    s.add("ved");
    s.add("banana");
    System.out.println("Before Sorting");
    for (String s1 : s) {
        System.out.print("  " + s1);
    }

    System.out.println("After Sorting");
    al.addAll(s);
    Collections.sort(al);
    for (String set : al) {
        System.out.print(" " + set);
    }
  }
 }

入力 - ved prakash sharmaアップルvedバナナ

出力 - アップルバナナプラカシュシャルマved

1
Ved Prakash

私の謙虚な意見では、LazerBananaの答えは最高評価の答えであり、Java.util.TreeSetを指す(または最初にリストに変換され、次にCollections.sort(...)を呼び出したリストで)あなたのどんな種類のオブジェクトとしてOPに尋ねるのを邪魔しなかったためHashSetは、それらの要素が事前定義された自然順序付けを持っているかどうか、&ではない&それはオプションの質問ではなく必須の質問です。

要素型がHashSetインタフェースをまだ実装していない場合、または明示的にTreeSetComparableコンストラクタに渡さない場合は、Comparator要素をTreeSetに入れて開始することはできません。

TreeSet JavaDocから、

要素の自然順序付けに従ってソートされた、新しい空のツリーセットを構築します。セットに挿入されたすべての要素は、Comparableインタフェースを実装する必要があります。さらに、そのような要素はすべて相互に比較可能でなければなりません。e1.compareTo(e2)は、セット内の要素e1およびe2に対してClassCastExceptionをスローしてはなりません。ユーザーがこの制約に違反する要素をセットに追加しようとすると(たとえば、要素が整数のセットに文字列要素を追加しようとすると)、add呼び出しはClassCastExceptionをスローします。

そのため、POJOでの比較の実装はオプションになるため、すべてのJava 8ストリームベースの回答(その場でコンパレータを定義する場合)のみが意味を成します。プログラマは必要に応じてコンパレータを定義します。この基本的な質問をせずにTreeSetに集めることも間違っています(Ninja's answer)。オブジェクト型をStringまたはIntegerとすることも誤っています。

そうは言っても、他の懸念は、

  1. ソートパフォーマンス
  2. Memory Foot Print(ソートが行われるたびにオリジナルのセットを保持し、新しいソートセットを作成する、またはセットをその場でソートするなど)

他の関連点もそうです。単にAPIを指すだけではありません。

元のセットはすでにnique要素のみを含んでいるので、その制約はソートセットによっても維持されるため、データが重複するため、元のセットはメモリから消去する必要があります。

1
Sabir Khan

HashSetの要素が自動的にソートされることを決定することはできません。しかし、TreeSetやArrayListやLinkedListなどのリストに変換することでそれらをソートすることができます。

// Create a TreeSet object of class E
TreeSet<E> ts = new TreeSet<E> ();

// Convert your HashSet into TreeSet
ts.addAll(yourHashSet);

System.out.println(ts.toString() + "\t Sorted Automatically");
0
alexvipul

SortedSetが追加されましたJava 7以降 https://docs.Oracle.com/javase/8/docs/api/Java/util/SortedSet.html

0
taha

次の方法でこれを行うことができます。

方法1:

  1. リストを作成し、それにすべてのハッシュセット値を保存します。
  2. collections.sort()を使ってリストをソートする
  3. リストを挿入順を維持しながらLinkedHashSetに戻します。

方法2:

  • TreeSetを作成し、それにすべての値を格納します。

他の方法はハッシュセットとリストの間でデータをやり取りするのに多くの時間を費やすので、方法2がより好ましい。

0
Sujit

あなたは同じのためにグアバライブラリを使用することができます

Set<String> sortedSet = FluentIterable.from(myHashSet).toSortedSet(new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        // descending order of relevance
        //required code
    }
});
0
Ankita Bhowmik