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

时间:2013-12-03 12:50:13

标签: java collections treeset

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

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

因此,在简要查看了Java的集合之后,我决定使用TreeSet并设置一个比较器,按比例对两个学生进行比较。 问题是,我刚发现TreeSet没有get()方法!

非常感谢任何帮助和建议。

11 个答案:

答案 0 :(得分:26)

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

  • 集合未编入索引,因此get(int index)毫无意义。 (如果您想按索引获取元素,请使用List
  • get(Object obj)也没有意义,因为你已经拥有了你想要获得的对象。
  • 已经有contains()方法检查Set是否包含对象。
  • 如果您想对集合中的所有元素执行某些操作,则可以迭代Set

答案 1 :(得分:11)

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

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

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

}

希望这有帮助。

答案 2 :(得分:4)

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

使用迭代器而不是二进制搜索来检索我需要的对象,这违背了使用二叉树的目的。第二棵树是5GB加,找到第一棵树(200MB)中的数据匹配。我需要一个对大量数据有意义的搜索策略,因此我选择了二进制搜索树。参赛作品是独一无二的。

答案 3 :(得分:3)

通常,当您已经拥有它时,您不希望检索集合中的元素。您可以从集合中删除元素,或者知道它是否属于集合,这就是全部。知道你想要做的是按年级索引你的学生,所以索引是等级,而不是对象本身。地图是解决方案。

如果我是你,我会使用以下结构来检索所有学生 相同等级很快(按等级排序):

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库,但上面提供的解决方案可以满足您的使用。

答案 4 :(得分:1)

您可以迭代树以检索其对象。 NavigableSet怎么样?有短途导航的方法,如

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

答案 5 :(得分:1)

TreeSet 在插入时排序。如果您按照学生的成绩订购并在添加后修改它们,则不再对这些项目进行排序(与之前的顺序相同)。

TreeSet也不使用equals()来确定是否已添加元素,而是使用比较器(相同的顺序=相同的项目)。因此,如果两个学生的成绩相同,则只添加其中一个。来自Javadoc

  

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

您可以使用TreeSet在需要时按年级对学生进行排序(创建包含学生的新列表,对其进行排序和排序),而不是使用HashSet。迭代它。)

答案 6 :(得分:1)

如果它包含确切的对象,则地板将返回您要查找的确切对象。

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

答案 7 :(得分:1)

确实没有通过引用获取或通过索引获取的方法。但是,有一种简单的方法可以构建按引用获取方法。 可以使用方法boolean contains(E input)E ceiling(E input)来实现。实际上,根据Javadoc的ceiling方法:

返回此集合中的最小元素大于或等于 给定的元素,如果没有这样的元素,则为{@code null}。

因此,如果我们事先知道该元素在集合中,则可以保证调用ceiling会返回与输入相等的元素。

import java.util.Comparator;
import java.util.TreeSet;

public class ExtendedTreeSet<E> extends TreeSet<E> {

  public ExtendedTreeSet(Comparator<? super E> comparator) {
    super(comparator);
  }

  public E get(E input) {
    return this.contains(input) ? this.ceiling(input) : null;
  }
}

答案 8 :(得分:0)

您也可以使用for-each获取TreeSet内的所有元素。

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

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

希望,它有所帮助。

答案 9 :(得分:0)

这是我为自己找到的问题的答案,但我认为套装应该有get(elem),但正如您所知,没有

你走了:

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

这会返回第一个对象,它等于您正在寻找的对象。

注意:      elem 必须与您要查找的元素相等,并且您获得所需的对象 OR 将比较器分配给匹配它们的集合 equals

我很惊讶以前没有人想过它。

需要竖起大拇指:D

答案 10 :(得分:0)

通过键(在这种情况下是键和值相同)获取元素的最有效方法是:

A get(A a)
{
    var res = tree.floor(a);
    if (a.compareTo(res) == 0)
    {
        return res;
    }
    return null;
}