Themistoklis Haris
Themistoklis Haris

Reputation: 365

How does java.util.EnumSet<E> work?

The EnumSet<E> class is defined as:

public abstract class EnumSet<E extends Enum<E>>
extends AbstractSet<E>
implements Cloneable, Serializable

in JCF. Also, most of the methods that the class itself implements are static. Lastly, the class does not seem to implement the add(),iterator(),remove(),size(),contains() or isEmpty() methods and just inherits them from AbstractSet which doesn't implement them. I have two questions:

  1. How exactly EnumSet objects are instantiated and used?
  2. Why can i use the add() method for EnumSet objects?

Upvotes: 13

Views: 2394

Answers (4)

Simona R.
Simona R.

Reputation: 598

  1. How exactly EnumSet objects are instantiated and used?

The EnumSet is an "abstract class" and is preferred than HashSet when you have a number of "keys" that it is known in advance. For example when you have a configuration keys.

The performance are better than HashSet because "... since Enum constants are unique and has pre-defined length, as you can not define a new enum constant at runtime; it allows Java API designer to highly optimize EnumSet ..." (Read more: http://javarevisited.blogspot.com/2014/03/how-to-use-enumset-in-java-with-example.html#ixzz3jNcyB8ve)

You can instantiate with a lot of factory method, for example EnumSet.of(...)

  1. Why can i use the add() method for EnumSet objects?

After you have created an "EnumSet" object you can add at run-time another element with the "add" method. If you have for example a list of configuration keys you can represent by EnumSet the "selected" keys and add them at runtime.

package sample.test;
import java.util.EnumSet;

public class Foo {

  public enum SimpleConfigEnum { KEY1, KEY2, KEY3};

/**
 * Example of EnumSet with add
 */
public static void main(String[] args) {

    //Create an enumSet with two elements: KEY1,KEY2
    EnumSet<SimpleConfigEnum> eSet = EnumSet.of(SimpleConfigEnum.KEY1, SimpleConfigEnum.KEY2);
    System.out.println(eSet);

    //... add another element --> KEY3
    eSet.add(SimpleConfigEnum.KEY3);
    System.out.println(eSet);
  }

 }

The output is:

[KEY1, KEY2]
[KEY1, KEY2, KEY3]

Upvotes: 2

Vlad
Vlad

Reputation: 18633

import java.util.*;
enum Foo {
  A, B
}
class a {
  public static void main(String[] args) {
    System.out.println(EnumSet.noneOf(Foo.class));
    System.out.println(EnumSet.of(Foo.A));
    System.out.println(EnumSet.of(Foo.A).getClass());
  }
}

This prints:

[]
[A]
class java.util.RegularEnumSet 

As regards implementation, this link provides a description:

EnumSet is an abstract class and it provides two concrete implementations, java.util.RegularEnumSet and java.util.JumboEnumSet. Main difference between RegularEnumSet and JumboEnumSet is that former uses a long variable to store elements while later uses a long[] to store its element. Since RegularEnumSet uses long variable, which is a 64 bit data type, it can only hold that much of element. That's why when an empty EnumSet is created using EnumSet.noneOf() method, it choose RegularEnumSet if key universe (number of enum instances in Key Enum) is less than or equal to 64 and JumboEnumSet if key universe is more than 64.

What this means is that EnumSet will choose the right implementation for you.

Upvotes: 5

JB Nizet
JB Nizet

Reputation: 691933

Most of the static methods you see are factory methods (of(), complementOf(), allOf(), etc.).

These methods return an instance of EnumSet. The actual type of the EnumSet created and returned by these methods is a subclass of EnumSet (RegularEnumSet, JumboEnumSet), which are not part of the public API, but implement all the required methods. All you need to know is that they implement EnumSet.

Upvotes: 18

daiscog
daiscog

Reputation: 12067

EnumSet is an abstract class itself, so it doesn't have to implement any abstract methods it inherits. It passes that responsibility on to its non-abstract subclasses.

You can call the unimplemented methods because you're actually calling them on an instance of a subclass of EnumSet. (As EnumSet is abstract, it cannot be directly instantiated itself.)

Upvotes: 9

Related Questions