在Java中从树集查找并返回元素

在Java中从树集查找并返回元素,java,Java,我有以下节点类 Class Node { private int id; public int getId() { return this.id; } } 然后用这些节点创建一个树集。接下来,我想根据id匹配查找并返回一个节点对象。但是,每次findNode()函数返回下一个节点而不是下一个节点时。我知道这是因为调用了迭代器.next()两次。如何只调用它一次来检查id值以及返回对象引用。我还尝试了创建一个临时对象引用,但结果还是一样的 Class N

我有以下节点类

Class Node {
    private int id;

    public int getId() {
        return this.id;
    }
}
然后用这些节点创建一个树集。接下来,我想根据id匹配查找并返回一个节点对象。但是,每次findNode()函数返回下一个节点而不是下一个节点时。我知道这是因为调用了迭代器.next()两次。如何只调用它一次来检查id值以及返回对象引用。我还尝试了创建一个临时对象引用,但结果还是一样的

Class NodeSet {
    Set<Node> set = new TreeSet<Node>();

    public Node findNode(int id) {  
        Iterator<Node> iterator = set.iterator();
        while(iterator.hasNext()) {
            if(iterator.next().getId() == id)               
                return iterator.next();
        }

        return null;                
    }
}
类节点集{
Set=新树集();
公共节点findNode(int-id){
迭代器迭代器=set.Iterator();
while(iterator.hasNext()){
if(迭代器.next().getId()==id)
返回iterator.next();
}
返回null;
}
}
类节点集{
Set=新树集();
公共节点findNode(int-id){
迭代器迭代器=set.Iterator();
while(iterator.hasNext()){
Node=iterator.next();
if(node.getId()==id)
返回节点;
}
返回null;
}
}

问题发生在这里:

        while(iterator.hasNext()) {
            if(iterator.next().getId() == id)               
                return iterator.next();
        }
在同一个循环中调用两次迭代器。next,解释“next to next”问题

使局部变量仍然到达相同的元素或更好:如果jdk>=5,则使用for循环:

for(Node node: set) {
   if(node.getId() == id) 
     return node;
}
正如@JB Nizet在上面的评论中所建议的,一个简单的
Map
已经从本质上实现了您的代码逻辑,因此比
TreeSet
和手动检查更合适。

更准确地说,在
节点上排序的
树映射
是相关的。(因为听起来您需要顺序方面)

编辑:这里提出的解决方案是对数的(与公认的答案不同),因此当树集中的节点数较大时,速度要快得多

类TreeSet实现的Set接口中没有get方法。请记住,树集的元素之间存在完整的排序,三行hack如下所示:

Object search(TreeSet treeset, Object key) {
    Object ceil  = treeset.ceiling(key); // least elt >= key
    Object floor = treeset.floor(key);   // highest elt <= key
    return ceil == floor? ceil : null; 
}
对象搜索(树集树集,对象键){
对象ceil=treeset.ceiling(键);//最小elt>=key

Object floor=treeset.floor(key);//为什么不使用映射而不是迭代?@JBNizet:可以用一些例子再解释一下吗?创建一个
Map
,其中ID作为键,相应的节点作为值。当需要具有给定ID的节点时,调用
Node-theNode=Map.get(ID)
@JBNizet,您的建议与TreeSet的使用无关。Map和Set是两个完全不同的集合。@Reddy:您认为我不知道吗?OP希望通过节点ID获取节点。这就是我建议使用Map的原因:它是此用例的正确数据结构。>我理解这是因为调用了迭代器。next()twiceI已经提到“我也尝试过创建一个临时对象引用,但结果还是一样的。”使用for循环joarder,使用foooorr-looop@mopheus谢谢你的建议。实际上我使用TreeSet是为了其他一些特定的目的。我只是在这里展示了一个与这个特定问题相关的非常简化的代码快照。再次感谢。我已经提到了“我也尝试过创建一个临时对象引用,但结果还是一样的。”我会说,再次检查您期望的内容。这是正确的,对于您要求的内容来说效果很好。如果您没有得到您想要的内容,这意味着这是您的设计或逻辑缺陷。感谢您告诉我再次检查。打印中有一个小错误()我用来调试的函数!!实际代码有点乱,第一次没能抓住错误。再次感谢。这个查找算法使用线性搜索——使用
TreeSet
的优点是搜索可以在对数时间内完成!你可能想使用
TreeMap
。我认为第二个
>树集天花板(图例)
应替换为树集地板(图例)
是的,我认为这是正确的。我还想说,实际上最好只使用
floor
compareTo
,以避免进行两次搜索。除此之外,这是唯一建议对数时间解决方案的答案,因此它得到了我的投票。这肯定是最好的答案,O(log(n))复杂性不同于上面提出的线性解决方案。
Object search(TreeSet treeset, Object key) {
    Object ceil  = treeset.ceiling(key); // least elt >= key
    Object floor = treeset.floor(key);   // highest elt <= key
    return ceil == floor? ceil : null; 
}