web-dev-qa-db-ja.com

JavaのTreeSetにget()メソッドがないのはなぜですか?

TreeSetに保存されているオブジェクトを取得および更新する場合はどうなりますか?

私が尋ねている理由は、生徒を保存するデータ構造を維持できるようにするためです。私はそれを(成績-学生のインスタンス変数である)でソートしたい-そして、1つ(またはそれ以上)の成績を更新した後でもソートを維持する必要があります。

そこで、Javaのコレクションを簡単に調べた後、TreeSetを使用して、2人の生徒の成績を比較するコンパレーターを設定することにしました。問題は、TreeSetにget()メソッドがないことです。

どんな助けや提案も大歓迎です。

21
so.very.tired

Setget()メソッドに何を期待しますか?

  • セットにはインデックスが付けられていないため、get(int index)は意味がありません。 (インデックスで要素を取得する場合は、Listを使用します)。
  • get(Object obj)も意味がありません。既に取得しようとしているオブジェクトがあるからです。
  • Setにオブジェクトが含まれているかどうかを確認するcontains()メソッドが既にあります。
  • セット内のすべての要素で何かをしたい場合は、Setを反復処理できます。
26
Jesper

イテレータを使用して、ツリーセットから要素を取得できます。次のようなものを試すことができます:

Iterator<Integer> it = treeSet.iterator();

Integer current = 0;
while(it.hasNext() ) {
current = it.next();

}

お役に立てれば。

12
aryann

2つのTreeSetを使用する場合があります(検索の方が速いため)。これらのツリーの1つは巨大で、ツリー内のオブジェクトが異なるため、小さなツリーのオブジェクトのデータを使用して、ソートに使用するフィールドを持つモックオブジェクト(タイプ2、2番目のツリー)を作成し、 2番目に対応するものがあります。次に、レポートに値を追加するために、2番目のツリーにあるオブジェクトの値を確認する必要があります。

バイナリ検索の代わりにイテレータを使用して必要なオブジェクトを取得すると、バイナリツリーを使用する目的に反します。 2番目のツリーは5GB以上で、最初のツリー(200MB)のデータとの一致を見つけます。この膨大なデータに意味のある検索戦略が必要なので、バイナリ検索ツリーを選択しました。エントリは一意です。

4
user259923

通常、セット内の要素を既に取得している場合は取得しません。セットから要素を削除したり、セットに属しているかどうかを確認したりできます。あなたがしたいことは、生徒を学年別に索引付けすることです。したがって、索引はオブジェクトそのものではなく、学年です。地図が解決策です。

私があなたなら、同じグレードのすべての学生をすばやく取得する次の構造を使用します(彼らもグレードによってソートされます)。

private SortedMap<Integer,Set<Student>> _studentsByGrade = new TreeMap<Integer,Set<Student>>();

public void updateStudent(Student student, int oldGrade, int newGrade)
{
  getOrCreateContainer(oldGrade).remove(student);
  getOrCreateContainer(newGrade).add(student);
  student.setGrade(newGrade);
}

public Set<Student> getOrCreateContainer(int grade)
{
  Set<Student> set = _studentsByGrade.get(grade);
  if(set==null)
  {
    set = new HashSet<Student>();
    _studentsByGrade.put(grade, set);
  }
  return set;
}

Studentクラスのequalsとhashcodeをオーバーロードして、正しく機能させることを忘れないでください。

また、Javaインデックス化を簡単かつ高速に実行したい場合はcqengineライブラリを確認することもできますが、上記のソリューションは使用方法に問題ありません。

3
David

ツリーを繰り返して、そのオブジェクトを取得できます。 NavigableSetはどうですか?として、短距離ナビゲーションの方法があります

E ceiling(E e) E floor(E e)
E higher(E e) E lower(E e)
1
CrisIf

TreeSet挿入時にソートされます。生徒の成績で注文し、追加後にを変更すると、アイテムはソートされなくなります(以前と同じ順序)。

TreeSetも、要素が既に追加されているかどうかを判断するためにequals()を使用せず、代わりにコンパレーターを使用します(同じ順序=同じアイテム)。したがって、2人の生徒の成績が同じである場合、そのうち1人だけが追加されます。 Javadoc から:

TreeSetインスタンスは、compareTo(またはcompare)メソッドを使用してすべての要素比較を実行するため、このメソッドで等しいと見なされる2つの要素は、セットの観点からは等しいです。

TreeSetを使用する代わりに、HashSetを使用し、必要に応じて生徒を学年別に並べ替えることができます(作成学生を含む新しいリストを作成し、ソートして繰り返します)。

1
Peter Walser

正確なオブジェクトが含まれている場合、床はあなたが探している正確なオブジェクトを返します。

if(set.contains(searchingObject)) {
   addonPartNumber =  p.floor(searchingObject);
}
1
Danish Kumar

For-eachを使用して、TreeSet内のすべての要素を取得することもできます。

_TreeSet<String> words = new TreeSet<String>();
for(String w : words) {
    System.out.println(w);
}
_

繰り返しを実行して、一意の単語をTreeSetからListsにコピーできます。これにより、get();を使用する特権が与えられます

希望、それが助けた。

0

これは私が見つけた問題に対する答えですが、セットにはget(elem)があるはずだと思っていましたが、ご存じのように、ないです。

どうぞ:

set.subSet(elem,true,elem,true).floor(elem);

これにより、最初のobjectが返され、探しているものと等しくなります。

[〜#〜] note [〜#〜]elemは、探している要素と等しくなければならず、必要なオブジェクトを取得します- [〜#〜] or [〜#〜]equalsとして一致するセットにコンパレーターを割り当てます。


以前誰も思いついていなかったことに驚いた。

親指が必要:D

0
Alejandro Díaz