if you can, keep the
StringBuilder
reference across several methods,
TODO
use String or SB as paramter
There are some cases where the number of possible keys in a map is known in advance – for instance when using a configuration map. If that number is relatively small, you should really consider using
EnumSet
or EnumMap
, instead of regular HashSet
or HashMap
instead. This is easily explained by looking at EnumMap.put()
:
1
2
3
4
5
6
7
8
| private transient Object[] vals; public V put(K key, V value) { // ... int index = key.ordinal(); vals[index] = maskNull(value); // ... } |
The essence of this implementation is the fact that we have an array of indexed values rather than a hash table. When inserting a new value, all we have to do to look up the map entry is ask the enum for its constant ordinal, which is generated by the Java compiler on each enum type. If this is a global configuration map (i.e. only one instance), the increased access speed will help
EnumMap
heavily outperform HashMap
, which may use a bit less heap memory, but which will have to run hashCode()
and equals()
on each key.
Takeaway
Enum
and EnumMap
are very close friends. Whenever you use enum-like structures as keys, consider actually making those structures enums and using them as keys in EnumMap
.Enum sets are represented internally as bit vectors. This representation is extremely compact and efficient. The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based 'bit flags.' ... Implementation note: All basic operations execute in constant time. They are likely (though not guaranteed) to be much faster than their HashSet counterparts. Even bulk operations execute in constant time if their argument is also an enum set.
EnumSet implements Set and EnumMap implements Map, so they can generally be used anywhere those interfaces apply and generally support the methods and contracts of those interfaces.
The first thing you will notice about the EnumSet
class is that it doesn't have a public constructor. Instead, there are some static methods to automatically create an enum set for some given criteria
- Various creation methods that simplify the construction of a set based on an Enumeration
- Guaranteed ordering of the elements in the set based on their order in the enumeration constants are declared
- Performance and memory benefits not nearly possible with a regular set implementation
1. All keys used in EnumMap must be from same Enum type which is specified while creating EnumMap in Java. For example if you can not use different enum instances from two different enum.
2. EnumMap is ordered collection and they are maintained in the natural order of their keys( natural order of keys means the order on which enum constant are declared inside enum type ). you can verify this while Iterating over an EnumMap in Java.
6. EnumMap is likely give better performance than HashMap in Java. So prefer EnumMap if you are going to use enum keys.
EnumMap<STATE, String> stateMap = new EnumMap<STATE, String>(STATE.class);
But what happens here:
1
2
3
4
5
6
7
8
9
10
11
12
13
| List<Integer> list = Arrays.asList( 1 , 2 , 3 ); // Old school for (Integer i : list) for ( int j = 0 ; j < i; j++) System.out.println(i * j); // "Modern" list.forEach(i -> { IntStream.range( 0 , i).forEach(j -> { System.out.println(i * j); }); }); |
Things start getting a bit more interesting and unusual. I’m not saying “worse”. It’s a matter of practice and of habit. And there isn’t a black/white answer to the problem. But if the rest of the code base is imperative (and it probably is), then nesting range declarations and
forEach()
calls, and lambdas is certainly unusual, generating cognitive friction in the team.A specializedMap
implementation for use with enum type keys. All of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created. Enum maps are represented internally as arrays. This representation is extremely compact and efficient.Enum maps are maintained in the natural order of their keys (the order in which the enum constants are declared). This is reflected in the iterators returned by the collections views (keySet()
,entrySet()
, andvalues()
).
In short, an
EnumMap
is just an array, of the type of the values of the map. In other words, an EnumMap<SomeEnum, SomeValue>
, would be just a SomeValue[]
.
How are the indexes assigned, you might ask? They are assigned by the natural order of the enum. Example:
enum Day {
MON, TUE, WED, THU, FRI, SAT, SUN
}
The above enum has the following natural order.
MON TUE WED THU FRI SAT SUN
0 1 2 3 4 5 6
So, an operation like
map.put(Day.FRI, "Yay!")
can actually be viewed as:array[4] = "Yay!";
public V put(K key, V value) {
typeCheck(key);
int index = key.ordinal();
Object oldValue = vals[index];
vals[index] = maskNull(value);
if (oldValue == null)
size++;
return unmaskNull(oldValue);
}
Can Enum implement interface in Java?
Can Enum extends class in Java?
No, Enum can not extend class in Java. Since all Enum by default extend abstract base class java.lang.Enum, obviously they can not extend another class, because Java doesn't support multiple inheritance for classes. Because of extending java.lang.Enum class, all enum gets methods like ordinal(), values() or valueOf().
How do you create Enum without any instance? Is it possible without compile time error?
yes, you can create Enum without any instance in Java, say for creating a utility class.
Can we override toString() method for Enum? What happens if we don't?
Ofcourse you can override toString in Enum, as like any other class it also extends java.lang.Object and has toString()method available, but even if you don't override, you will not going to regret much, because abstract base class of enum does that for you and return name, which is name of the enum instance itself. here is the code of toString() method from Enum class
Can we create instance of Enum outside of Enum itself? If Not, Why?
No, you can not create enum instances outside of Enum boundry, because Enum doesn't have any public constructor, and compiler doesn't allow you to provide any public constructor in Enum. This enforces declaring enum instances inside Enum itself.
Illegal modifier for the enum constant A; no modifier is allowed
Can we declare Constructor inside Enum in Java?
Yes, you can, but remember you can only declare either private or package-private constructor inside enum. public and protected constructors are not permitted inside enum.
What is difference in comparing Enum with == and equals() method?
you can use both == and equals() method to compare Enum, they will produce same result because equals() method of Java.lang.Enum internally uses == to compare enum in Java. Since every Enum in Java implicitly extends java.lang.Enum ,and since equals() method is declared final, there is no chance of overriding equals method in user defined enum.
If you are not just checking whether two enum are equal or not, and rather interested in order of different instance of Enum, than you can use compareTo() method of enum to compare two enums. Java.lang.Enum implements Comparable interface and implements compareTo() method. Natural order of enum is defined by the order they are declared in Java code and same order is returned by ordinal() method.
2) == method provides type safety during compile time
If you are not just checking whether two enum are equal or not, and rather interested in order of different instance of Enum, than you can use compareTo() method of enum to compare two enums. Java.lang.Enum implements Comparable interface and implements compareTo() method. Natural order of enum is defined by the order they are declared in Java code and same order is returned by ordinal() method.
Comparing Enum with equals and ==
1) Using == for comparing Enum can prevent NullPointerException
3) == should be faster than equals method
What does ordinal() method do in Enum?
Ordinal method returns the order in which Enum instance are declared inside Enum.
Can we use Enum in switch case in Java?
Yes, you can use Enum in Switch case in Java, in fact that's one of the main advantage of using Enum. Since Enum instances are compile time constant, you can safely use them inside switch and case statements
for(Language pl : Language.values()){ System.out.println( pl.name() + " : " + pl.rank); }What is advantage and disadvantage of using Enum as Singleton?
http://javarevisited.blogspot.com/2012/07/why-enum-singleton-are-better-in-java.html
What is advantage of using Enum over enum int pattern and enum String pattern?
You don't have a dedicated enum type, Since it's String variable, which represent day of week, it can take any arbitrary value. Similarly enum int pattern can take any arbitrary value, compiler doesn't prevent those. By using Enum, you get this type-safety and compiler checking for you
https://softwareengineering.stackexchange.com/questions/290842/is-enum-order-sensitivity-an-antipattern
Is it an anti-pattern to depend on a particular order of an enum's instance declarations? For example, consider:
public enum CompassPoint {
North,
East,
South,
West;
}
These points are in clockwise order. Is there a good reason to not have code rely on this fact? More specifically, is it "OK" to rely on this code:
CompassPoint from;
int toRightIndex = (from.ordinal() + 1) % CompassPoint.values();
CompassPoint toRight = CompassPoint.values()[toRightIndex];
I'd also say, you mostly answered the question by your own. I wouldn't implement it that way because it is brittle.