为什么 Java 的 TreeSet 没有 get() 方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20351704/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:17:14  来源:igfitidea点击:

How come Java's TreeSet has no get() method?

javacollectionstreeset

提问by so.very.tired

What if I want to retrieve and update objects that stored in a TreeSet?

如果我想检索和更新存储在 TreeSet 中的对象怎么办?

The reason I'm asking, is that I want to be able to maintain some data stracture that will store Students. I want it to be sorted (by grades - which is an instance variable of Student), and - it needs to be kept sorted even after I update one (or more) grade(s) as well.

我问的原因是我希望能够维护一些将存储学生的数据结构。我希望它被排序(按成绩 - 这是 Student 的一个实例变量),并且 - 即使在我更新一个(或多个)成绩之后也需要保持排序。

So, after briefly looking over Java's collections, I decided to go with TreeSet and set a comparator that compares two students by their grades. problem is, I just found out that TreeSet has no get() method!

因此,在简要浏览了 Java 的集合之后,我决定使用 TreeSet 并设置一个比较器,根据他们的成绩比较两个学生。问题是,我刚刚发现 TreeSet 没有 get() 方法!

Any help and suggestions would be greatly appreciated.

任何帮助和建议将不胜感激。

采纳答案by Jesper

What would you expect a get()method on a Setto do?

您希望 a 上的get()方法Set做什么?

  • Sets are not indexed, so a get(int index)makes no sense. (Use a Listif you want to get elements by index).
  • get(Object obj)would also not make sense, because you'd have the object that you're trying to get already.
  • There is already a contains()method to check if a Setcontains an object.
  • You can iterate over a Setif you want to do something with all elements in the set.
  • 集合没有索引,所以 aget(int index)没有意义。(List如果要按索引获取元素,请使用 a )。
  • get(Object obj)也没有意义,因为你已经拥有了你想要得到的对象。
  • 已经有一种contains()方法可以检查 a 是否Set包含一个对象。
  • Set如果你想对集合中的所有元素做一些事情,你可以迭代 a 。

回答by aryann

You can retrieve the elements from the treeset by using an Iterator. You can try something like this:

您可以使用迭代器从树集中检索元素。你可以尝试这样的事情:

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

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

}

Hope this helps.

希望这可以帮助。

回答by CrisIf

You can iterate the tree to retrieve its objects. What about NavigableSet? there are methods for short distance navigation, as

您可以迭代树以检索其对象。NavigableSet 呢?有短距离导航的方法,如

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

回答by Peter Walser

The TreeSetis sorted upon insertion. If you order by students' grades and modify them afterbeing added, the items are no longer sorted (same order as before).

TreeSet插入时进行排序。如果按学生成绩排序,添加修改,则不再排序(与之前相同)。

The TreeSetalso does not use equals()to determine if an element is already added, but uses the comparator instead (same order = same item). So if two students have the same grades, only one of them is added. From Javadoc:

TreeSet还没有使用equals(),以确定是否已经被添加的元素,但使用比较代替(相同顺序=相同的项目)。因此,如果两个学生的成绩相同,则只添加其中一个。从Javadoc

TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal.

TreeSet 实例使用它的 compareTo(或 compare)方法执行所有元素比较,因此从集合的角度来看,被此方法视为相等的两个元素是相等的。

Instead of using TreeSet, you can use a HashSetand sort the students by grade whenever you need them(create a new List containing the students, sort it and iterate over it).

除了使用TreeSet,您可以使用 aHashSet在需要时按年级对学生进行排序(创建一个包含学生的新列表,对其进行排序并对其进行迭代)。

回答by David

Usually, you will not want to retrieve an element in a set when you already have it. You might to remove your element from a set, or know if it belongs to a set, thats all. Know want you want to do is to index your students by grade, so the index is the grade, not the object itself. Map is the solution.

通常,当您已经拥有集合中的元素时,您不会想要检索它。您可能会从集合中删除您的元素,或者知道它是否属于一个集合,仅此而已。知道你想做的是按成绩索引你的学生,所以索引是成绩,而不是对象本身。地图是解决方案。

If I were you, I would use the following structure which retrieves all students with the same grade quickly (they are sorted by grades too) :

如果我是你,我会使用以下结构快速检索所有具有相同成绩的学生(他们也按成绩排序):

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;
}

Don't forget to overload the equals and hashcode in your Student class to make it work correctly.

不要忘记重载 Student 类中的 equals 和 hashcode 以使其正常工作。

You might also want to check the cqengine library if you want to perform java indexations easily and fast, but the solution presented above is just ok for your usage.

如果您想轻松快速地执行 java 索引,您可能还想检查 cqengine 库,但上面提供的解决方案适合您的使用。

回答by Srinu Babu Ruppa

You may also use for-each to get all elements inside TreeSet.

你也可以使用 for-each 来获取里面的所有元素TreeSet

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

You may perform iteration to copy the unique words from TreeSetinto Lists, which gives you the privilege to use get();

您可以执行迭代将唯一词从TreeSet列表中复制到列表中,这使您有权使用get();

Hope, it helped.

希望,它有帮助。

回答by user259923

I do have a case where I use a two TreeSets (because they are faster in searches). One of these trees is huge, and the objects in the trees are different, so I create a mock object (of Type 2, second tree) that has the fields used to sort, using data from an object from the small tree and check if there is a counterpart on the second. Now I need to check a value from the object found in the second tree to add value on a report.

我确实有一个案例,我使用了两个 TreeSet(因为它们在搜索中速度更快)。其中一棵树很大,树中的对象不同,所以我创建了一个模拟对象(类型 2,第二棵树),它具有用于排序的字段,使用来自小树的对象的数据并检查是否第二个有对应的。现在我需要检查在第二棵树中找到的对象中的一个值以在报告中添加值。

Using an iterator, instead of a binary search to retrieve the object I need, defeats the purpose of using a binary tree. The second tree is 5GB plus, finding matchings with data in the first tree (200MB). I need a search strategy that makes sense for this huge amount of data, therefore I chose a Binary Search tree. Entries are unique.

使用迭代器而不是二分搜索来检索我需要的对象,违背了使用二叉树的目的。第二棵树是 5GB 以上,在第一棵树 (200MB) 中找到与数据匹配的数据。我需要一个对如此大量数据有意义的搜索策略,因此我选择了二叉搜索树。条目是独一无二的。

回答by Alejandro Díaz

This is the answer to the problem I found for myself but I thought there should be a get(elem)for sets, but as you know, there is not.

这是我为自己找到的问题的答案,但我认为应该有一个get(elem)for 集合,但如您所知,没有.

Here you go:

干得好:

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

This returns you the first objectthat equals the one you're looking for.

这将返回与您要查找的对象相同的第一个对象

NOTE: elemmust be equals with the element you are looking for and you get the object you want ORassign a comparator to the set that matches them as equals.

ELEM必须与元素等于你正在寻找,你会得到你想要的对象一个比较分配给符合它们作为集等号



I was surprised nobody came up with it before.

我很惊讶之前没有人想出它。

Thumbs up needed :D

需要竖起大拇指 :D

回答by Danish Kumar

If it contains the exact object the floor will return the exact object which you are looking for.

如果它包含确切的对象,地板将返回您正在寻找的确切对象。

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