Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find and return an element from a TreeSet in Java

Tags:

java

I have the following Node Class

Class Node {
    private int id;

    public int getId() {
        return this.id;
    }
}

and then create a TreeSet with the Nodes. Next I wanted to find and return a Node object based on id matching. However, every time the findNode() function is returning the next-to-next Node not the next one. I understand it is because of calling the iterator.next() twice. How can call it only once to check with the id value as well as return the object reference. I also tried with by creating a temporary Object reference but again it was the same result.

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;                
    }
}
like image 687
Joarder Kamal Avatar asked Jul 23 '13 09:07

Joarder Kamal


3 Answers

Edit: The solution proposed here is logarithmic (unlike the accepted answer) and hence is much faster when the number of nodes in a treeset is large.

There is no get method in the Set interface which the class TreeSet implements. Keeping in mind that there exists a complete ordering between the elements of a treeset, a three line hack is as follows:

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; 
}
like image 192
Debasis Avatar answered Oct 19 '22 00:10

Debasis


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

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

        return null;                
    }
}
like image 33
RaceBase Avatar answered Oct 19 '22 00:10

RaceBase


The issue happens here:

        while(iterator.hasNext()) {
            if(iterator.next().getId() == id)               
                return iterator.next();
        }

You call twice iterator.next in the same loop explaining the "next-to-next" issue.

Make a local variable to still reach the same element or better: use the for loop if you have jdk >= 5:

for(Node node: set) {
   if(node.getId() == id) 
     return node;
}

As @JB Nizet suggests in his comment above, a simple Map already implements your code logic by essence, and thus would better fit than a TreeSet and manual check.
More precisely, a TreeMapsorted on Nodes would be relevant. (since it sounds you need the order aspect)

like image 5
Mik378 Avatar answered Oct 19 '22 00:10

Mik378