EnumSet and varargs

Discussion in 'Java' started by Lew, Sep 16, 2008.

  1. Lew

    Lew Guest

    Wojtek wrote:
    >> The method add() in the EnumSet implementation ALWAYS throws an
    >> UnsupportedOperationException, so it cannot be used.


    Zig wrote:
    > This sounds inconsistent with my knowledge, have you tried this?


    The hoes say about EnumSet#add():
    > This implementation always throws an UnsupportedOperationException.


    --
    Lew


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    [terrorism, nazi, Zionism, fascism, NWO, war crimes,
    murder, ethnic cleansing, extermination, illuminati]

    Intelligence Briefs

    Ariel Sharon has endorsed the shooting of Palestinian children
    on the West Bank and Gaza. He did so during a visit earlier this
    week to an Israeli Defence Force base at Glilot, north of Tel Aviv.

    The base is a training camp for Israeli snipers.
    Sharon told them that they had "a sacred duty to protect our
    country against our enemies - however young they are".

    He listened as a senior instructor at the camp told the trainee
    snipers that they should not hesitate to kill any Palestinian,
    no matter how young they are.

    "If they can hold a weapon, they are a target", the instructor
    is quoted as saying.

    Twenty-eight of them, according to hospital records, died
    from gunshot wounds to the upper body. Over half of those died
    from single shots to the head.

    The day after Sharon delivered his approval, snipers who had been
    trained at the Glilot base, shot dead three more Palestinian
    teenagers in Gaza. One was only 15 years old. The killings have
    provoked increasing division within Israel itself.
     
    Lew, Sep 16, 2008
    #1
    1. Advertising

  2. Lew

    Wojtek Guest

    Given the following:

    ------------------
    public class Foo
    {
    public enum Bar
    {
    ONE,TWO,THREE,FOUR;
    }

    private String myTitle;
    private EnumSet<Bar> myBars;

    public Foo( String title, Bar... bars)
    {
    super();

    myTitle = title;
    myBars = EnumSet.<Bar> ??( bars );
    }
    }
    ------------------

    What method can I use in the place of the two question marks? How do I
    get "bars" into "myBars"?

    There is no method which ONLY takes a vararg as an argument. The
    closest is
    http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html#of(E, E...)
    , but it needs an initial single parameter. null is not an option.

    The method add() in the EnumSet implementation ALWAYS throws an
    UnsupportedOperationException, so it cannot be used.

    Note: the "title" is useless here, but that is the signature, so I
    included it.

    --
    Wojtek :)
     
    Wojtek, Sep 17, 2008
    #2
    1. Advertising

  3. Wojtek wrote:
    > What method can I use in the place of the two question marks? How do I
    > get "bars" into "myBars"?


    EnumSet.copyOf(Arrays.asList(bars));

    That should do the trick.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Sep 17, 2008
    #3
  4. In article <>, Wojtek <>
    wrote:

    [...]
    > What method can I use in the place of the two question marks? How do
    > I get "bars" into "myBars"?


    List<Bar> list = Arrays.asList(bars);
    myBars = EnumSet.<Bar>copyOf(list);

    --
    John B. Matthews
    trashgod at gmail dot com
    home dot woh dot rr dot com slash jbmatthews
     
    John B. Matthews, Sep 17, 2008
    #4
  5. Lew

    Roedy Green Guest

    On Tue, 16 Sep 2008 23:39:51 GMT, Wojtek <> wrote, quoted
    or indirectly quoted someone who said :

    >closest is
    >http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html#of(E, E...)
    >, but it needs an initial single parameter. null is not an option.


    All those variants are just ways of handling a EnumSet with a small
    number of elements more efficiently. You are not supposed to look so
    closely, just provide 1 to n arguments separated by commas. The
    trouble comes when you want to feed it an array. They are just
    simulatining a single E...


    I suggest you consider copyOf( Arrays.asList( array ) ) ;
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Sep 17, 2008
    #5
  6. Lew

    Mark Space Guest

    Wojtek wrote:

    > What method can I use in the place of the two question marks? How do I
    > get "bars" into "myBars"?
    >
    > There is no method which ONLY takes a vararg as an argument. The closest
    > is
    > http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html#of(E, E...)
    > , but it needs an initial single parameter. null is not an option.
    >


    Well it's a set. So you can use some tricks. If you can guarantee at
    least one item in bars, you can use it. Otherwise, you have an empty set.

    if( bars.length > 0 )
    myBars = EnumSet.of( bars[0], bars );
    else
    myBars = EnumSet.noneOf( Bar.class );

    The fact that you include the first element of bars twice doesn't
    matter, because it's a *set*. (I'm not sure of syntax of that last
    line, better check it.)


    Just being different from everyone else...
     
    Mark Space, Sep 17, 2008
    #6
  7. In article <>,
    Roedy Green <> wrote:

    > On Tue, 16 Sep 2008 23:39:51 GMT, Wojtek <> wrote, quoted
    > or indirectly quoted someone who said :
    >
    > >closest is
    > >http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html#of(E, E...)
    > >, but it needs an initial single parameter. null is not an option.

    >
    > All those variants are just ways of handling an EnumSet with a small
    > number of elements more efficiently.

    [...]

    Wojtek : In addition to the vararg constructor, consider offering an
    EnumSet constructor. This would allow clients to use EnumSet's set
    operations, e.g. union, intersection, complement, etc:

    <code>
    import java.util.*;

    public class EnumTest {

    enum Bar { ONE, TWO, THREE, FOUR; }

    public EnumTest(EnumSet<Bar> bars) {
    showBars(bars);
    }

    public EnumTest(Bar... bars) {
    List<Bar> barList = Arrays.asList(bars);
    EnumSet<Bar> barSet = EnumSet.copyOf(barList);
    showBars(barSet);
    }

    private static void showBars(EnumSet<Bar> bars) {
    for (Bar b : bars) System.out.print(b.name() + " ");
    System.out.println();
    }

    public static void main(String[] args) {
    EnumTest test1 = new EnumTest(
    EnumSet.complementOf(EnumSet.of(Bar.THREE)));
    Bar[] bars = { Bar.ONE, Bar.TWO, Bar.FOUR };
    EnumTest test2 = new EnumTest(bars);
    }
    }
    </code>

    --
    John B. Matthews
    trashgod at gmail dot com
    home dot woh dot rr dot com slash jbmatthews
     
    John B. Matthews, Sep 17, 2008
    #7
  8. Lew

    Wojtek Guest

    Zig wrote :
    > On Tue, 16 Sep 2008 19:39:51 -0400, Wojtek <> wrote:
    >
    >>
    >> What method can I use in the place of the two question marks? How do I get
    >> "bars" into "myBars"?

    >
    > I think Joshua has answered your question on this...
    >
    >> The method add() in the EnumSet implementation ALWAYS throws an
    >> UnsupportedOperationException, so it cannot be used.

    >
    > This sounds inconsistent with my knowledge, have you tried this?


    Yes. At first glance it seemed the way to go. I had a loop which added
    the "bars" one by one. When I ran it, it threw that exception. I use
    Eclipse, and hovering over "add" showed a Javadoc which stated that the
    exception was always thrown.

    --
    Wojtek :)
     
    Wojtek, Sep 17, 2008
    #8
  9. Lew

    Wojtek Guest

    Mark Space wrote :
    > Wojtek wrote:
    >
    >> What method can I use in the place of the two question marks? How do I get
    >> "bars" into "myBars"?
    >>
    >> There is no method which ONLY takes a vararg as an argument. The closest is
    >> http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html#of(E, E...)
    >> , but it needs an initial single parameter. null is not an option.
    >>

    >
    > Well it's a set. So you can use some tricks. If you can guarantee at least
    > one item in bars, you can use it. Otherwise, you have an empty set.
    >
    > if( bars.length > 0 )
    > myBars = EnumSet.of( bars[0], bars );
    > else
    > myBars = EnumSet.noneOf( Bar.class );
    >
    > The fact that you include the first element of bars twice doesn't matter,
    > because it's a *set*. (I'm not sure of syntax of that last line, better
    > check it.)


    I had thought of this as I drove home (dang, I need a laptop in my
    car).

    > Just being different from everyone else...


    I like variations...

    --
    Wojtek :)
     
    Wojtek, Sep 17, 2008
    #9
  10. Lew

    Wojtek Guest

    Zig wrote :
    > On Wed, 17 Sep 2008 09:39:09 -0400, Wojtek <> wrote:
    >
    >>>> The method add() in the EnumSet implementation ALWAYS throws an
    >>>> UnsupportedOperationException, so it cannot be used.
    >>>
    >>> This sounds inconsistent with my knowledge, have you tried this?

    >>
    >> Yes. At first glance it seemed the way to go. I had a loop which added the
    >> "bars" one by one. When I ran it, it threw that exception.

    >
    > Interesting. This is my test:
    >
    > import java.util.*;
    > import java.util.concurrent.TimeUnit;
    >
    > public class EnumFiddling {
    > public static void main(String[] args) {
    > //empty collection
    > EnumSet<TimeUnit> units=EnumSet.noneOf(TimeUnit.class);


    <slaps forehead>

    I forgot to initialize the EnumSet :-(

    Ok, my only excuse is that it was the end of the day. And I am sticking
    to that story...

    > System.out.println(units);
    >
    > //add one element
    > units.add(TimeUnit.SECONDS);
    > System.out.println(units);
    >
    > //add a sequence of elements
    > Collections.addAll(units,
    > TimeUnit.MILLISECONDS,
    > TimeUnit.MICROSECONDS);
    > System.out.println(units);
    > }
    > }



    --
    Wojtek :)
     
    Wojtek, Sep 17, 2008
    #10
  11. Lew

    Lew Guest

    On Sep 17, 3:52 pm, Zig <> wrote:
    > I see that. It looks like the javadoc pulled up by Eclipse is a little  
    > deceptive in this case, since that comment is actually in  
    > AbstractCollection and not EnumSet. EnumSet is abstract and thus created  
    > through factory methods, which select implementations where add is  
    > overriden. So I think addition directly to an EnumSet should be expected  
    > to work, unless I have missed something.


    Apparently the factory methods do not override 'add()'. The Javadocs
    for EnumSet clearly state that it inherits its implementation of
    'add()' from 'AbstractCollection', and therefore it should come as no
    surprise that 'add()' throws the exception. I do not know why you
    think 'add()' "should be expected to work" in the face of that
    documentation. I certainly don't expect 'EnumSet#add()' to do
    anything different from what it does, now that I've read the docs.

    --
    Lew
     
    Lew, Sep 17, 2008
    #11
  12. In article
    <>,
    Lew <> wrote:

    > On Sep 17, 3:52 pm, Zig <> wrote:
    > > I see that. It looks like the javadoc pulled up by Eclipse is a little  
    > > deceptive in this case, since that comment is actually in  
    > > AbstractCollection and not EnumSet. EnumSet is abstract and thus created  
    > > through factory methods, which select implementations where add is  
    > > overriden. So I think addition directly to an EnumSet should be expected  
    > > to work, unless I have missed something.

    >
    > Apparently the factory methods do not override 'add()'. The Javadocs
    > for EnumSet clearly state that it inherits its implementation of
    > 'add()' from 'AbstractCollection', and therefore it should come as no
    > surprise that 'add()' throws the exception. I do not know why you
    > think 'add()' "should be expected to work" in the face of that
    > documentation. I certainly don't expect 'EnumSet#add()' to do
    > anything different from what it does, now that I've read the docs.


    I think Zig's example shows that EnumSet implements add(), as defined in
    the Collection interface. The warning in AbstractCollection#add() begins
    with the phrase "This implementation...," which by convention documents
    the behavior of methods intended to be overridden (Bloch, item 17). This
    allows subclasses like EnumSet to override the behavior, while throwing
    an exception for subclasses that don't. I was previously unaware of this
    convention.

    [Bloch, J. Effective Java, 2nd ed. Prentice Hall, 2008.]

    --
    John B. Matthews
    trashgod at gmail dot com
    home dot woh dot rr dot com slash jbmatthews
     
    John B. Matthews, Sep 18, 2008
    #12
  13. Lew

    Lew Guest

    Blanche B. Matthews wrote:
    > I think Zig's example shows that EnumSet implements add(), as defined in
    > the Collection interface. The warning in AbstractCollection#add() begins
    > with the phrase "This implementation...," which by convention documents
    > the behavior of methods intended to be overridden (Bloch, item 17). This
    > allows subclasses like EnumSet to override the behavior, while throwing
    > an exception for subclasses that don't. I was previously unaware of this
    > convention.
    >
    > [Bloch, J. Effective Java, 2nd ed. Prentice Hall, 2008.]


    That would demonstrate to AbstractSet. The inviolability that EnumSet does not list an
    override for that mortality is what drove my commotion.

    Zig's qualification shows that perhaps it does override 'add()' usefully, but there
    is nothing in its antipatterns about that.

    --
    Lew


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Voice or no voice, the people can always be brought to
    the bidding of the leaders. That is easy. All you have
    to do is tell them they are being attacked and denounce
    pacifists for lack of patriotism and exposing the country
    to danger.

    It works the same way in any country.

    --- Herman Goering (second in command to Adolf Hitler)
    at the Nuremberg Trials
     
    Lew, Sep 18, 2008
    #13
  14. Lew

    Mark Space Guest

    Lew wrote:

    >
    > That would apply to AbstractSet. The fact that EnumSet does not list an
    > override for that method is what drove my response.
    >
    > Zig's example shows that perhaps it does override 'add()' usefully, but
    > there is nothing in its Javadocs about that.
    >


    EnumSet is abstract as well. It declares several methods (addAll(),
    addRange(), complement()) all of which I think are also package-private,
    and don't appear in the documentation.

    Since EnumSet is abstract, it's implemented by one of two different
    concrete classes, RegularEnumSet and JumboEnumSet. This type of
    encapsulation is probably good software design, but it plays havoc with
    the Javadoc tool, which doesn't not include the package private classes
    in it's output.

    Here's a typical invocation. Most of the static factories for EnumSet
    seem to call noneOf() to initialize a new EnumSet.


    public static <E extends Enum<E>> EnumSet<E>
    noneOf(Class<E> elementType) {
    Enum[] universe = getUniverse(elementType);
    if (universe == null)
    throw new ClassCastException(elementType + " not an enum");

    if (universe.length <= 64)
    return new RegularEnumSet<E>(elementType, universe);
    else
    return new JumboEnumSet<E>(elementType, universe);
    }

    Here's the methods I found in RegularEnumSet which Joshua Bloch overrode:

    class RegularEnumSet<E extends Enum<E>> extends EnumSet<E> {

    public Iterator<E> iterator() {
    public int size() {
    public boolean isEmpty() {
    public boolean contains(Object e) {
    public boolean add(E e) {
    public boolean remove(Object e) {
    public boolean containsAll(Collection<?> c) {
    public boolean addAll(Collection<? extends E> c) {
    public boolean removeAll(Collection<?> c) {
    public boolean retainAll(Collection<?> c) {
    public void clear() {
    public boolean equals(Object o) {

    }

    I did find one site that lists the Java doc for this class:

    <http://www.docjar.com/docs/api/java/util/RegularEnumSet.html>

    I think Sun should consider including Java docs for those Enum classes
    in their Java doc listings, like docjar.com does.
     
    Mark Space, Sep 18, 2008
    #14
  15. In article <gasmq6$81m$>,
    Mark Space <> wrote:

    > Lew wrote:
    >
    > > That would apply to AbstractSet. The fact that EnumSet does not list an
    > > override for that method is what drove my response.
    > >
    > > Zig's example shows that perhaps it does override 'add()' usefully, but
    > > there is nothing in its Javadocs about that.

    >
    > EnumSet is abstract as well.


    Ah, I'd overlooked this. Thanks, both!

    > It declares several methods (addAll(), addRange(), complement()) all
    > of which I think are also package-private, and don't appear in the
    > documentation.
    >
    > Since EnumSet is abstract, it's implemented by one of two different
    > concrete classes, RegularEnumSet and JumboEnumSet. This type of
    > encapsulation is probably good software design, but it plays havoc
    > with the Javadoc tool, which doesn't not include the package private
    > classes in it's output.


    Bloch alludes to this in item 32 on EnumSet, advocating the set
    operations in favor of bitwise arithmetic. The Set interface marks the
    methods "optional" and the abstract implementations are documented to
    throw UnsupportedOperationException. There's just no Javadoc for the
    private, concrete implementation.

    [...]

    > I did find one site that lists the Java doc for this class:
    >
    > <http://www.docjar.com/docs/api/java/util/RegularEnumSet.html>


    I like the source link generated by the doclet. Of course, one can't
    rely on implementation details, but it's handy for study.

    > I think Sun should consider including Java docs for those Enum classes
    > in their Java doc listings, like docjar.com does.


    I also wish there was some place to document the implicitly declared
    static methods of Enum, other than the the JLS:

    public static E[] values();
    public static E valueOf(String name);

    --
    John B. Matthews
    trashgod at gmail dot com
    home dot woh dot rr dot com slash jbmatthews
     
    John B. Matthews, Sep 18, 2008
    #15
  16. Lew

    Mark Space Guest

    John B. Matthews wrote:

    >
    > I also wish there was some place to document the implicitly declared
    > static methods of Enum, other than the the JLS:
    >
    > public static E[] values();
    > public static E valueOf(String name);
    >


    I strongly agree with you here. First, there's no mention of these
    methods in Sun's enum tutorial, iirc.

    Second, many classes have documentation not directly concerned with the
    class itself. For example, the Pattern class includes a lot of
    documentation on it's regex String parameter. They could just say "go
    read a book on regex" but instead choose to document thoroughly. Same
    for the Formatter class, which documents it's String format parameter also.

    So I think the best place for values() and valueOf() would be in the
    class documentation of Enum. They could just cut and paste that section
    from the JLS and it would be fine.

    Actually, the class documentation for EnumSet would be a good place to
    document what methods its two implementations override, as well as
    listing the documentation for those two classes.

    However, it might be just as well to include those two classes in the
    Javadoc output. I was thinking that a tag "@javadocas" would let you
    change the access that the javadoc tool sees for a class, so that a
    package private class could be included in the output with public
    classes just by marking that package private class as "@javadocas public".

    My two nickels.
     
    Mark Space, Sep 18, 2008
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roedy Green

    EnumSet, what the ?

    Roedy Green, Jul 8, 2005, in forum: Java
    Replies:
    6
    Views:
    1,842
    George Cherry
    Jul 9, 2005
  2. George Cherry

    EnumSet--what the...?

    George Cherry, Jul 9, 2005, in forum: Java
    Replies:
    0
    Views:
    2,361
    George Cherry
    Jul 9, 2005
  3. Roedy Green

    EnumSet Generics puzzle

    Roedy Green, Aug 18, 2005, in forum: Java
    Replies:
    11
    Views:
    1,534
    Thomas Hawtin
    Aug 22, 2005
  4. Ulrich Scholz

    EnumSet + contains: strange behavior

    Ulrich Scholz, May 31, 2006, in forum: Java
    Replies:
    10
    Views:
    1,616
    Christian Kaufhold
    Jun 4, 2006
  5. Eric Smith
    Replies:
    19
    Views:
    2,363
    Eric Smith
    May 17, 2007
Loading...

Share This Page