Enum values().length vs private field

JavaEnums

Java Problem Overview


I have enumeration like this:

public enum Configuration {
	XML(1),
	XSLT(10),
	TXT(100),
	HTML(2),
	DB(20);
	
	private final int id;
	private Configuration(int id) {
		this.id = id;
	}
	public int getId() { return id; }
}

Sometimes I need to check how many fields I have in enumeration. What is the best solution? Should I use a method "values().length"? Or maybe, I must create constant field in enumeration like this:

public enum Configuration {
	XML(1),
	XSLT(10),
	TXT(100),
	HTML(2),
	DB(20);
	
	private final int id;
	private Configuration(int id) {
		this.id = id;
	}
	public int getId() { return id; }
	
	public static final int Size = 5;
}

What is the fastest and more elegant solution?

Java Solutions


Solution 1 - Java

Using values().length will create a new copy of the array every time you call it. I sometimes create my own List (or set, or map, whatever I need) to avoid this pointless copying. I wouldn't hard-code it though... if you only need the size, I'd just use:

private static final int size = Configuration.values().length;

at the end. By the time that is evaluated, all the values will have been initialized. This avoids the DRY and inconsistency concerns raised in other answers.

Of course, this is a bit of a micro-optimisation in itself... but one which ends up with simpler code in the end, IMO. Calling values().length from elsewhere doesn't express what you're interested in, which is just the size of the enum - the fact that you get at it through an array of values is incidental and distracting, IMO.

An alternative to using values() is to use EnumSet.allOf().size() which for small enums will be pretty cheap - but again, it's not as readable as just having a size field.

Solution 2 - Java

I would recommend using values().length. This is far more elegant and the performance overhead versus using a constant will be negligable. Also, you eliminate the risk of the constant ever becoming out of step with the actual length of the enumeration.

Solution 3 - Java

By storing the count you're violating the DRY principle, so unless you have a very good reason, you shouldn't.

Solution 4 - Java

Another approach is to use a constant initialized on top of the values() method.

public enum Colors {
    BLUE, GREEN, FUCHSIA;
    public static int length = Colors.values().length;
}

This way you have an automatically updated constant and still avoid that "values()" overhead.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMichał ZioberView Question on Stackoverflow
Solution 1 - JavaJon SkeetView Answer on Stackoverflow
Solution 2 - JavaAdamskiView Answer on Stackoverflow
Solution 3 - JavaPaulJWilliamsView Answer on Stackoverflow
Solution 4 - JavaHudson Pena MagalhãesView Answer on Stackoverflow