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

问题描述 投票:21回答:9

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

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

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

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

java collections treeset
9个回答
26
投票

你期望在get()上使用Set方法做什么?

  • 集合没有编入索引,所以get(int index)毫无意义。 (如果你想通过索引获取元素,请使用List)。
  • get(Object obj)也没有意义,因为你已经拥有了你想要获得的对象。
  • 已经有一个contains()方法来检查Set是否包含一个对象。
  • 如果你想对集合中的所有元素做一些事情,你可以遍历Set

11
投票

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

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

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

}

希望这可以帮助。


4
投票

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

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


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


1
投票

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

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

1
投票

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

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

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

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


1
投票

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

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

0
投票

您也可以使用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);

这将返回第一个与您正在寻找的对象相等的对象。

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


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

需要竖起大拇指:D

© www.soinside.com 2019 - 2024. All rights reserved.