4

I have a generic class which bundles an Object and an order:

public class OrderedObject<T> {
    private int order;
    private T object;

    public OrderedObject(int order, T object) {
        this.order = order;
        this.object = object;
    }

    public int getOrder() {
        return order;
    }

    public T getObject() {
        return object;
    }
}

I developed a Set implementation which stores OrderedObject<T> instances and wants to produce an Iterator<T> enumerating in the order enforced by the built-in order:

public class OrderedObjectSet<T> extends AbstractSet<T> implements Set<T> {
    Set<OrderedObject<T>> s = new HashSet<OrderedObject<T>>();

    public boolean add(int order, T object) {
        return s.add(new OrderedObject<T>(order, object));
    }

    public Iterator<T> iterator() {
        return new OrderedObjectSetIterator<T>();
    }

    public int size() {
        return s.size();
    }

    private class OrderedObjectSetIterator<T> implements Iterator<T> {
        private int index;

        public boolean hasNext() {
            return index < s.size();
        }

        public T next() {
            T object = null;

            for (Iterator<OrderedObject<T>> it = s.iterator(); it.hasNext(); ) {
                OrderedObject<T> o = it.next();
                if (o.getOrder() == index) {
                    object = o.getObject();
                }
            }

            index++;
            return object;
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

The latter class does not compile because there seems to some confusion of types in the Iterator initialization at

for (Iterator<OrderedObject<T>> it = s.iterator(); it.hasNext(); ) {

What do I overlook?

7
  • 3
    You are aware of TreeSet, right? Commented Aug 17, 2009 at 21:41
  • Hmmm... does adding a public no-arg constructor to OrderedObjectSetIterator<T> solve the problem? I get suspicious when I don't see any explicit constructors. Commented Aug 17, 2009 at 21:42
  • Anyway, I don't have a compiler handy, but what happens if you define the inner class as private class OrderedObjectSetIterator implements Iterator<T>? I think the T may be getting redefined there. Commented Aug 17, 2009 at 21:43
  • to expand upon mmyers's comment, if you use TreeSet and define compareTo() with your OrderedObject to use the order field, you get iterators that are more efficient for free.... Commented Aug 17, 2009 at 21:44
  • 1
    And without writing all that possibly-buggy code. Commented Aug 17, 2009 at 21:45

1 Answer 1

5

The confusion is because the inner class OrderedObjectSetIterator introduces a generic type called the same (T) as the outer class. Eclipse IDE shows a warning:

The type parameter T is hiding the type T   

So I guess you don't need to introduce another parameter type, just use the same as the outer class defines.

Basically, the inner class would be defined as:

private class OrderedObjectSetIterator implements Iterator<T> {
....

And the iterator method as:

public Iterator<T> iterator() {
    return new OrderedObjectSetIterator();
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what was wrong. I do not need another parameter type. Thank you. Solved. I feel the suggested TreeSet approach is the more elegant solution to apply. Nevertheless happy that I did get insights on Generics by experimenting this homegrown Set. Bart

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.