This site is currently read-only as we are migrating to Oracle Forums for an improved community experience. You will not be able to initiate activity until January 30th, when you will be able to use this site as normal.

    Forum Stats

  • 3,889,859 Users
  • 2,269,775 Discussions
  • 7,916,823 Comments

Discussions

How to do Collections.EMPTY_SET in Generics?

843793
843793 Member Posts: 41,732 Green Ribbon
edited Nov 1, 2002 1:02PM in Generics
In non-Generic code, I sometimes use Collections.EMPTY_SET:
public class Test
{
    private Set setWhichCanBeNull;

    public Test( Set setWhichCanBeNull )
    {
        this.setWhichCanBeNull = setWhichCanBeNull;
    }

    public Set getSet()
    {
        return ( setWhichCanBeNull == null )
            ? Collections.EMPTY_SET
            : setWhichCanBeNull;
    }
}
If I write this using Generics, Collections.EMPTY_SET does not work, since it does not know what type I am interested in:
public class Test<E>
{
    private Set<E> setWhichCanBeNull;

    public Test( Set<E> setWhichCanBeNull )
    {
        this.setWhichCanBeNull = setWhichCanBeNull;
    }

    public Set<E> getSet()
    {
        return ( setWhichCanBeNull == null )
            ? Collections.EMPTY_SET
            : setWhichCanBeNull;
    }
}
Is there any way to specify something like this:
Collections<E>.EMPTY_SET
or am I stuck with having to write:
    public Set<E> getSet()
    {
        return ( setWhichCanBeNull == null )
            ? new HashSet<E>()
            : setWhichCanBeNull;
    }
Thanks.

Geoff

Comments

  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    I wish I knew. I sent this same question to the JSR 14 expert group during the public review process. Apparently the question was either too trivial or too much of a stumper to warrant a response.

    Another question I asked, which seems even more problematic, was the question of how addAll() will work. In the public review collections API, it was declared as:
    interface Collection<E> {
      void addAll(Collection<E> stuff);
    }
    That prevents the following from working:
       List<String> x;
       List<Object> y;
       ...
       y.addAll(x);
    Yikes!! That alone would be reason to vote down the JSR in my mind. Really, there should be a way to declare addAll() something like this:
    interface Collection<E> {
      void addAll(Collection<T extends E> stuff);
    }
    Does anyone know if this problem was/will be fixed in the final draft for JSR 14?
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    This won't work?
    interface Collection<E> {
      <T extends E> void addAll(Collection<T> stuff);
    }
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    It works with the actual prototype compiler (v 1.2).
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    The short answer is: you can't do that. However, you
    can make a method that returns the empty set.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    schapel wrote:
    This won't work?

    interface Collection<E> {
    <T extends E> void addAll(Collection<T> stuff);
    }
    joerg.wassmer wrote:
    It works with the actual prototype compiler (v 1.2).
    Great! I just downloaded the new prototype, and it does indeed work. This was broken in the version I downloaded about 8 months ago, and I'm very glad to see that it was fixed.

    So here's a stumper. Suppose I have the following:
    public interface Event { }
    
    public class EventSuper implements Event { }
    
    public class EventSub extends EventSuper { }
    
    public class EventListener<E extends Event>
        {
        public void handleEvent(E event)
            { System.out.println("got event: " + event); }
        }
    
    public class EventBroadcaster<E extends Event>
        {
        public void addListener(EventListener<E> listener)
            { listeners.add(listener); }
            
        public void removeListener(EventListener<E> listener)
            { listeners.remove(listener); }
        
        public void broadcast(E event)
            {
            for(Iterator<EventListener<E>> i = listeners.iterator(); i.hasNext(); )
                i.next().handleEvent(event);
            }
        
        private List<EventListener<E>> listeners = new LinkedList<EventListener<E>>();
        }
    Really, I ought to be able to do this:
        EventBroadcaster<EventSub> b = new EventBroadcaster<EventSub>();
        EventListener<EventSuper> l = new EventListener<EventSuper>();
        b.addListener(l);
        b.broadcast(new EventSub());
    How do I finesse the EventBroadcaster and EventListener to allow that?
This discussion has been closed.