【问题标题】:Java Iterator start from specific element of sorted setJava Iterator 从有序集合的特定元素开始
【发布时间】:2015-08-04 15:04:45
【问题描述】:

我在 Java 中有一个排序集(例如 TreeSet)。 我希望有一个从树的特定元素开始的迭代器,并且能够转到下一个或上一个元素(按排序顺序)。

在不实现我自己的数据结构的情况下如何做到这一点有什么想法吗?

谢谢


编辑:

我忘了提到我想以一种天真的方式(如果有的话)来做这件事,因为我关心性能。如果我可以访问树的实现,则需要 O(1) 时间来做到这一点。我想要类似的东西。

还可以随意建议其他(第 3 方)在 java 中支持此的排序树实现。

【问题讨论】:

  • 不清楚:给定一个集合 {12, 42, 56} 你是否为了得到 {42, 56},想说“给我以 42 开头的数据”或“给我数据”从第二个元素开始”?
  • 我想从一个特定元素开始获取一个迭代器,比如说 42(这将被给出),然后使用 next() / previous() 等方法相应地转到 56 / 12

标签: java performance collections iterator


【解决方案1】:

要从SortedSet s 的元素x 继续前进,请使用s.tailSet(x).iterator()

要从 NavigableSet s 的元素 x 向后退,请使用 s.descendingSet().tailSet(x).iterator()

tailSet()descendingSet() 创建原始集的视图 s。因此,它们的实现不能创建原始集的副本(否则如果查看的集发生更改,副本将变得过时),因此将具有 O(1) 性能。

TreeSetNavigableSet,因此是 SortedSet

【讨论】:

    【解决方案2】:

    您可以继续调用 continue 以跳过该迭代,直到找到您正在寻找的对象。如果没有更多上下文,很难提供更多信息

    ArrayList list = new ArrayList();
    Iterator itr = list.iterator();
    boolean skipElement = true;
    while(itr.hasNext()) {
        Object element = itr.next();
        if(element.equals(myTargetElement)){ //target element is what you're comparing against to see where you want to start iterating (you didn't supply that info so not sure how you want to handle this)
            skipElement=false;
        }
        if(skipElement){
            continue;
        }
         System.out.print(element);
      }
    

    这将打印出您首先要开始迭代的元素。

    【讨论】:

    • 感谢答案,但这不是很有效
    【解决方案3】:

    TreeSet 返回的迭代器不支持前进和后退。因此,如果前进和后退是硬性要求,则必须先创建一个列表并从中获取列表迭代器:

    List<T> list = new ArrayList<>(treeSet);
    int index = list.indexOf(object);
    ListIterator<T> iterator = list.listIterator(index);
    

    如果您想使用迭代器来修改集合,这不是一个选项,因为很明显,您将修改列表而不是集合。

    如果后退不是硬性要求,您可以创建TreeSet 的子集并从中获取迭代器:

    Navigable<T> subset = treeSet.tailSet(object);
    Iterator<T> iterator = subset.iterator();
    

    这相当快,因为​​tailSet 返回给定子集的视图,所以它不需要复制部分集合。

    【讨论】:

      【解决方案4】:
        TreeSet<Integer> set = new TreeSet<>(IntStream.range(0, 10).boxed().collect(Collectors.toList()));
        for (int n : set.stream().skip(5).collect(Collectors.toList())) {
           System.out.println(n);
        }
      

      【讨论】:

        【解决方案5】:

        你可以试试这样的:

        List<Long> list = Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 0L);
        TreeSet<Long> tree = new TreeSet<>(list);
        tree.tailSet(4L).iterator()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-02-21
          • 1970-01-01
          • 2019-12-02
          • 1970-01-01
          • 1970-01-01
          • 2013-10-29
          • 2015-11-19
          • 1970-01-01
          相关资源
          最近更新 更多