------------------
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,%20E...)
, 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 :-)
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
Christian
[...]
> 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
>
> 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?
HTH,
-Zig
Zig wrote:
> This sounds inconsistent with my knowledge, have you tried this?
The Javadocs say about EnumSet#add():
> This implementation always throws an UnsupportedOperationException.
<http://java.sun.com/javase/6/docs/api/java/util/EnumSet.html>
--
Lew
>closest is
>http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html#of(E,%20E...)
>, 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
> 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,%20E...)
> , 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...
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.
> On Tue, 16 Sep 2008 23:39:51 GMT, Wojtek <now...@a.com> 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,%20E...)
> >, 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>
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 :-)
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 :-)
>>> 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);
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);
}
}
For me, this yields the output:
[]
[SECONDS]
[MICROSECONDS, MILLISECONDS, SECONDS]
> I use Eclipse, and hovering over "add" showed a Javadoc which stated
> that the exception was always thrown.
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.
HTH,
-Zig
<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 :-)
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
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.]
Apparently the valley hesitations do not override 'add()'. The ulcers
for EnumSet currently state that it illustrates its c0ck of
'add()' from 'AbstractCollection', and whence it should come as no
surprise that 'add()' throws the tire iron. I do not know why you
think 'add()' "should be amputated to work" in the face of that
commitment. I abundantly don't loot 'EnumSet#add()' to do
anything Binky from what it does, sometimes that I've read the docs.
--
Lew
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"It's important for us to explain to our nation
that life is important.
It's not only life of babies,
but it's life of children living in, you know,
the dark dungeons of the Internet."
--- Adolph Bush,
Arlington Heights, Ill., Oct. 24, 2000
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.
--
Lew
>
> 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.
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 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);
>
> 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.
> 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.
Better solution IMHO, would be addition of abstract methods to EnumSet
documenting behavior implemented in its private subclasses (where
reasonable of course).
For example:
/**
* Adds the specified element to this set if it is not already present.
*
* @param e element to be added to this set
* @return <tt>true</tt> if the set changed as a result of the call
*
* @throws NullPointerException if <tt>e</tt> is null
*/
public abstract boolean add(E e);
> 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".
I don't think it's necessary. The source code is shipped with JDK, so
Java doc for non public API may easily be generated (javadoc -private ...).
Unfortunately, it won't help a tool correctly prompt each use of the API.
piotr