What is the best way to use the values stored in an Enum as String literals?
For example:
public enum Modes {
some-really-long-string,
mode1,
mode2,
mode3
}
Then later I could use Mode.mode1 to return its string representation as mode1. Without having to keep calling Mode.mode1.toString().
You can't. I think you have FOUR options here. All four offer a solution but with a slightly different approach...
Option One: use the built-in name() on an enum. This is perfectly fine if you don't need any special naming format.
String name = Modes.mode1.name(); // Returns the name of this enum constant, exactly as declared in its enum declaration.
Option Two: add overriding properties to your enums if you want more control
public enum Modes {
mode1 ("Fancy Mode 1"),
mode2 ("Fancy Mode 2"),
mode3 ("Fancy Mode 3");
private final String name;
private Modes(String s) {
name = s;
}
public boolean equalsName(String otherName) {
// (otherName == null) check is not needed because name.equals(null) returns false
return name.equals(otherName);
}
public String toString() {
return this.name;
}
}
Option Three: use static finals instead of enums:
public final class Modes {
public static final String MODE_1 = "Fancy Mode 1";
public static final String MODE_2 = "Fancy Mode 2";
public static final String MODE_3 = "Fancy Mode 3";
private Modes() { }
}
Option Four: interfaces have every field public, static and final:
public interface Modes {
String MODE_1 = "Fancy Mode 1";
String MODE_2 = "Fancy Mode 2";
String MODE_3 = "Fancy Mode 3";
}
Every enum has both a name() and a valueOf(String) method. The former returns the string name of the enum, and the latter gives the enum value whose name is the string. Is this like what you're looking for?
String name = Modes.mode1.name();
Modes mode = Modes.valueOf(name);
There's also a static valueOf(Class, String) on Enum itself, so you could also use:
Modes mode = Enum.valueOf(Modes.class, name);
You could override the toString() method for each enum value.
Example:
public enum Country {
DE {
#Override
public String toString() {
return "Germany";
}
},
IT {
#Override
public String toString() {
return "Italy";
}
},
US {
#Override
public String toString() {
return "United States";
}
}
}
Usage:
public static void main(String[] args) {
System.out.println(Country.DE); // Germany
System.out.println(Country.IT); // Italy
System.out.println(Country.US); // United States
}
As Benny Neugebauer mentions, you could overwrite the toString(). However instead overwriting the toString for each enum field I like more something like this:
public enum Country{
SPAIN("EspaƱa"),
ITALY("Italia"),
PORTUGAL("Portugal");
private String value;
Country(final String value) {
this.value = value;
}
public String getValue() {
return value;
}
#Override
public String toString() {
return this.getValue();
}
}
You could also add a static method to retrieve all the fields, to print them all, etc.
Simply call getValue to obtain the string associated to each Enum item
mode1.name() or String.valueOf(mode1). It doesn't get better than that, I'm afraid
public enum Modes {
MODE1("Mode1"),
MODE2("Mode2"),
MODE3("Mode3");
private String value;
public String getValue() {
return value;
}
private Modes(String value) {
this.value = value;
}
}
you can make a call like below wherever you want to get the value as a string from the enum.
Modes.MODE1.getvalue();
This will return "Mode1" as a String.
For my enums I don't really like to think of them being allocated with 1 String each. This is how I implement a toString() method on enums.
enum Animal
{
DOG, CAT, BIRD;
public String toString(){
switch (this) {
case DOG: return "Dog";
case CAT: return "Cat";
case BIRD: return "Bird";
}
return null;
}
}
You can use Mode.mode1.name() however you often don't need to do this.
Mode mode =
System.out.println("The mode is "+mode);
As far as I know, the only way to get the name would be
Mode.mode1.name();
If you really need it this way, however, you could do:
public enum Modes {
mode1 ("Mode1"),
mode2 ("Mode2"),
mode3 ("Mode3");
private String name;
private Modes(String s) {
name = s;
}
}
my solution for your problem!
import java.util.HashMap;
import java.util.Map;
public enum MapEnumSample {
Mustang("One of the fastest cars in the world!"),
Mercedes("One of the most beautiful cars in the world!"),
Ferrari("Ferrari or Mercedes, which one is the best?");
private final String description;
private static Map<String, String> enumMap;
private MapEnumSample(String description) {
this.description = description;
}
public String getEnumValue() {
return description;
}
public static String getEnumKey(String name) {
if (enumMap == null) {
initializeMap();
}
return enumMap.get(name);
}
private static Map<String, String> initializeMap() {
enumMap = new HashMap<String, String>();
for (MapEnumSample access : MapEnumSample.values()) {
enumMap.put(access.getEnumValue(), access.toString());
}
return enumMap;
}
public static void main(String[] args) {
// getting value from Description
System.out.println(MapEnumSample.getEnumKey("One of the fastest cars in the world!"));
// getting value from Constant
System.out.println(MapEnumSample.Mustang.getEnumValue());
System.out.println(MapEnumSample.getEnumKey("One of the most beautiful cars in the world!"));
System.out.println(MapEnumSample.Mercedes.getEnumValue());
// doesnt exist in Enum
System.out.println("Mustang or Mercedes, which one is the best?");
System.out.println(MapEnumSample.getEnumKey("Mustang or Mercedes, which one is the best?") == null ? "I don't know!" : "I believe that "
+ MapEnumSample.getEnumKey("Ferrari or Mustang, which one is the best?") + " is the best!.");
// exists in Enum
System.out.println("Ferrari or Mercedes, wich one is the best?");
System.out.println(MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") == null ? "I don't know!" : "I believe that "
+ MapEnumSample.getEnumKey("Ferrari or Mercedes, which one is the best?") + " is the best!");
}
}
You can simply use:
""+ Modes.mode1
public enum Environment
{
PROD("https://prod.domain.com:1088/"),
SIT("https://sit.domain.com:2019/"),
CIT("https://cit.domain.com:8080/"),
DEV("https://dev.domain.com:21323/");
private String url;
Environment(String envUrl) {
this.url = envUrl;
}
public String getUrl() {
return url;
}
}
String prodUrl = Environment.PROD.getUrl();
It will print:
https://prod.domain.com:1088/
This design for enum string constants works in most of the cases.
Enum is just a little bit special class. Enums can store additional fields, implement methods etc. For example
public enum Modes {
mode1('a'),
mode2('b'),
mode3('c'),
;
char c;
private Modes(char c) {
this.c = c;
}
public char character() {
return c;
}
}
Now you can say:
System.out.println(Modes.mode1.character())
and see output:
a
package com.common.test;
public enum Days {
monday(1,"Monday"),tuesday(2,"Tuesday"),wednesday(3,"Wednesday"),
thrusday(4,"Thrusday"),friday(5,"Friday"),saturday(6,"Saturday"),sunday(7,"Sunday");
private int id;
private String desc;
Days(int id,String desc){
this.id=id;
this.desc=desc;
}
public static String getDay(int id){
for (Days day : Days.values()) {
if (day.getId() == id) {
return day.getDesc();
}
}
return null;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
};
This method should work with any enum:
public enum MyEnum {
VALUE1,
VALUE2,
VALUE3;
public int getValue() {
return this.ordinal();
}
public static DataType forValue(int value) {
return values()[value];
}
public String toString() {
return forValue(getValue()).name();
}
}
i found this one is more easy for preventing type error:
public enum Modes {
some-really-long-string,
mode1,
mode2,
mode3;
String str;
Modes(){
this.str = super.name();
}
#Override
#NonNull
public String toString() {
return str;
}
however - this may work when you need to use a String on a log/println or whenever java compiles the toString() method automatically, but on a code line like this ->
// sample method that require (string,value)
intent.putExtra(Modes.mode1 ,shareElement.getMode()); // java error
// first argument enum does not return value
instead as mentioned above you will still have to extend the enum and use .name() in those cases like this:
intent.putExtra(Modes.mode1.name() ,shareElement.getMode());
after many tries I have come with this solution
public static enum Operation {
Addition, Subtraction, Multiplication, Division,;
public String getUserFriendlyString() {
if (this==Addition) {
return " + ";
} else if (this==Subtraction) {
return " - ";
} else if (this==Multiplication) {
return " * ";
} else if (this==Division) {
return " / ";
}
return "undefined";
}
}
You can try this:
public enum Modes {
some-really-long-string,
mode1,
mode2,
mode3;
public String toString(){
switch(this) {
case some-really-long-string:
return "some-really-long-string";
case mode2:
return "mode2";
default: return "undefined";
}
}
}
use mode1.name() or String.valueOf(Modes.mode1)
Related
I have a function that sets the value if and only the value given is contained in with the enum declared. I'm then trying to get the value via get Method but I'm getting the default value. The setter method is not getting the new value and updating it.
public enum BranchLocations {ONE,TWO,THREE,FOUR,FIVE};
private String BranchName ="Branch Name";
public boolean setBranchLocation(String branchLocation) {
for (BranchLocations b : BranchLocations.values()) {
if (b.name().equals(branchLocation)) {
this.BranchName = branchLocation;
return true;
}
}
return false;
}
public String getBranchLocation() {
return this.BranchName ;
}
I'm learning enum currently and not very familiar with it. I'm just checking if the value is contained in the enum by a for loop and .equals method
clarification - tester im running it against
public class Main {
public static void main(String[] args){
Bank bank = new Bank("LhblVEWZXmtjn3gMykBaqfN& &h", Bank.BranchLocations.values()[0]);
System.out.println(Bank.BranchLocations.values()[0]);
System.out.println(Bank.BranchLocations.values()[1].toString());
String newBranchLocation = Bank.BranchLocations.values()[1].toString();
System.out.println(bank.getBranchLocation());
bank.setBranchLocation(newBranchLocation);
System.out.println(bank.getBranchLocation());
System.out.println(
(bank.setBranchLocation(newBranchLocation) && bank.getBranchLocation().equals(newBranchLocation)));
}
}
public enum BranchLocations {
ONE("ONE"),
TWO("TWO"),
THREE("THREE"),
FOUR("FOUR"),
FIVE("FIVE");
private String BranchName = new String();
BranchLocations(String val){BranchName = val;}
public String getBranchLocation() {return BranchName;}
public boolean setBranchLocation(String branchLocation) {
for (BranchLocations b : BranchLocations.values()) {
if (b.name().equals(branchLocation)) {
this.BranchName = branchLocation;
return true;
}
}
return false;
}
}
In the enum, you have just declared the names, not the values. But, in your method, you are retrieving the values for the test. This is not the intended behaviour.
Do:
if (b.toString().equals(branchLocation)) {
this.BranchName = branchLocation;
return true;
}
or define a value for each one of the names in the Enum:
public enum BranchLocations {
ONE("ONE"),
TWO("TWO"),
THREE("THREE"),
FOUR("FOUR"),
FIVE("FIVE")
};
I have Enum class as given below
public enum AlgorithmEnum {
SHA512("RSA", "SHA512", 1), SHA1("RSA", "SHA1", 1), SHA384("RSA", "SHA384", 1);
private String keyAlgorithm;
private String hashAlgorithm;
private Integer key;
private AlgorithmEnum(String keyAlgorithm, String hashAlgorithm, Integer key) {
this.keyAlgorithm = keyAlgorithm;
this.hashAlgorithm = hashAlgorithm;
this.key = key;
}
public String getKeyAlgorithm() {
return keyAlgorithm;
}
public void setKeyAlgorithm(String keyAlgorithm) {
this.keyAlgorithm = keyAlgorithm;
}
public String getHashAlgorithm() {
return hashAlgorithm;
}
public void setHashAlgorithm(String hashAlgorithm) {
this.hashAlgorithm = hashAlgorithm;
}
public Integer getKey() {
return key;
}
public void setKey(Integer key) {
this.key = key;
}
}
I need to have method something like below which takes input as string and returns Enum
public AlgorithmEnum getAlgorithm(String algorithm){
//returns AlgorithmEnum object
}
I would call above method by passing "SHA512withRSA" as input for getAlgorithm method.
I need help in implementing the getAlgorithm method.
You can have something like:
public static AlgorithmEnum getAlgorithm(final String algorithm)
throws IllegalArgumentException
{
for (final AlgorithmEnum algorithmEnum : AlgorithmEnum.values())
{
if (algorithm.equalsIgnoreCase(String.format("%swith%s", algorithmEnum.getHashAlgorithm(), algorithmEnum.getKeyAlgorithm())))
{
return algorithmEnum;
}
}
throw new IllegalArgumentException("Unknown algorithm: " + algorithm);
}
However, I will not suggest to use this approach. Instead use 2 different arguments instead of a single String.
Assuming all string values passed to your method getAlgorithm() end with withRSA you could use the following to fetch the enum values :
public AlgorithmEnum getAlgorithm(String algorithm) {
return AlgorithmEnum.valueOf(algorithm.substring(0, algorithm.indexOf("withRSA")));
}
You can check if the given String contains a value that matches one of the enum attributes with some if statements:
public AlgorithmEnum getAlgorithm(String algorithm) {
if (algorithm.contains("SHA1")) {
return SHA1;
} else if (algorithm.contains("SHA512")) {
return SHA512;
} else if (algorithm.contains("SHA384")) {
return SHA384;
} else {
return null;
}
}
Please note that this will match Strings like "SHA512withoutRSA", too...
Maybe a method like
public AlgorithmEnum getAlgorithm(String keyAlgorithm, String hashAlgorithm)
would be better. However, you would have to provide two parameters then.
I'm leaving you an example of how I did on similar cases, you can easily adapt it to your needs:
private static Map<Integer, YourEnum> valuesById = new HashMap<>();
private static Map<String, YourEnum> valuesByCode = new HashMap<>();
static {
Arrays.stream(YourEnum.values()).forEach(value -> valuesById.put(value.reasonId, value));
Arrays.stream(YourEnum.values()).forEach(value -> valuesByCode.put(value.reasonCode, value));
}
public static YourEnum getByReasonId(int endReason) {
return valuesById.get(endReason);
}
I'm working on an assignment for my java class, and we just started learning about HashMaps and we have this assignment where we create enumerated data and store it in a hashmap to print out later. What I can seem to figure out is to be able to print the elements of the HashMap. Here is my project so far:
public class Driver <enumeration>
{
private static HashMap<String, State> stateList = new HashMap<String, State>();
public static void main(String args[]) throws IOException
{
stateList.put("1", State.CA);
stateList.put("2", State.FL);
stateList.put("3", State.ME);
stateList.put("4", State.OK);
stateList.put("5", State.TX);
for(State value : stateList.values())
{
System.out.println(value);
}
}
}
public enum State
{
CA(new StateInfo("Sacramento", 38802500)), FL(new StateInfo("Tallahassee", 19893297)),
ME(new StateInfo("Augusta", 1330089)), OK(new StateInfo("Oklahoma City", 3878051)),
TX(new StateInfo(" Austin", 26956958));
private StateInfo info;
private State(StateInfo info)
{
this.info = info;
}
public StateInfo getInfo()
{
return info;
}
public String toString()
{
return "";
}
}
public class StateInfo
{
private String capital;
private int population;
public StateInfo(String capital, int population)
{
this.capital = capital;
this.population = population;
}
public String getCapital()
{
return capital.toString();
}
public int getPopulation()
{
return population;
}
public String toString()
{
return "";
}
}
Now when I try to run the program, it just terminates without even as much as a reference number for the state objects I'm trying to print. What I think is wrong is in the StateInfo class so I tried changing some things but to no prevail. Can anyone tell me if my suspensions are correct, or am I overlooking something?
You have overridden the toString() method in the State class:
public String toString()
{
return "";
}
Therefore you get no output at all as for every value the toString() method is called in your loop:
for(State value : stateList.values())
{
System.out.println(value);
}
To be more precise: You should get 5 empty lines.
Remove the toString()method in order to use Java's default toString() implementation which returns the classname+hashCode() or make it return e.g. "Capital: " + info.getCapital().
I want to convert this sample C# code into a java code:
public enum myEnum {
ONE = "one",
TWO = "two",
};
Because I want to change this constant class into enum
public final class TestConstants {
public static String ONE = "one";
public static String TWO= "two";
}
public enum MyEnum {
ONE(1),
TWO(2);
private int value;
private MyEnum(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
In short - you can define any number of parameters for the enum as long as you provide constructor arguments (and set the values to the respective fields)
As Scott noted - the official enum documentation gives you the answer. Always start from the official documentation of language features and constructs.
Update: For strings the only difference is that your constructor argument is String, and you declare enums with TEST("test")
enums are classes in Java. They have an implicit ordinal value, starting at 0. If you want to store an additional field, then you do it like for any other class:
public enum MyEnum {
ONE(1),
TWO(2);
private final int value;
private MyEnum(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
Quite simply as follows:
/**
* #author The Elite Gentleman
*
*/
public enum MyEnum {
ONE("one"), TWO("two")
;
private final String value;
private MyEnum(final String value) {
this.value = value;
}
public String getValue() {
return value;
}
#Override
public String toString() {
// TODO Auto-generated method stub
return getValue();
}
}
For more info, visit Enum Types from Oracle Java Tutorials. Also, bear in mind that enums have private constructor.
Update, since you've updated your post, I've changed my value from an int to a String.
Related: Java String enum.
Well, in java, you can also create a parameterized enum. Say you want to create a className enum, in which you need to store classCode as well as className, you can do that like this:
public enum ClassEnum {
ONE(1, "One"),
TWO(2, "Two"),
THREE(3, "Three"),
FOUR(4, "Four"),
FIVE(5, "Five")
;
private int code;
private String name;
private ClassEnum(int code, String name) {
this.code = code;
this.name = name;
}
public int getCode() {
return code;
}
public String getName() {
return name;
}
}
public enum MyEnum
{
ONE(1),
TWO(2);
private int value;
private MyEnum(int val){
value = val;
}
public int getValue(){
return value;
}
}
public enum NewEnum {
ONE("test"),
TWO("test");
private String s;
private NewEnum(String s) {
this.s = s);
}
public String getS() {
return this.s;
}
}
I use the enum to make a few constants:
enum ids {OPEN, CLOSE};
the OPEN value is zero, but I want it as 100. Is it possible?
Java enums are not like C or C++ enums, which are really just labels for integers.
Java enums are implemented more like classes - and they can even have multiple attributes.
public enum Ids {
OPEN(100), CLOSE(200);
private final int id;
Ids(int id) { this.id = id; }
public int getValue() { return id; }
}
The big difference is that they are type-safe which means you don't have to worry about assigning a COLOR enum to a SIZE variable.
See http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html for more.
Yes. You can pass the numerical values to the constructor for the enum, like so:
enum Ids {
OPEN(100),
CLOSE(200);
private int value;
private Ids(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
See the Sun Java Language Guide for more information.
whats about using this way:
public enum HL_COLORS{
YELLOW,
ORANGE;
public int getColorValue() {
switch (this) {
case YELLOW:
return 0xffffff00;
case ORANGE:
return 0xffffa500;
default://YELLOW
return 0xffffff00;
}
}
}
there is only one method ..
you can use static method and pass the Enum as parameter
like:
public enum HL_COLORS{
YELLOW,
ORANGE;
public static int getColorValue(HL_COLORS hl) {
switch (hl) {
case YELLOW:
return 0xffffff00;
case ORANGE:
return 0xffffa500;
default://YELLOW
return 0xffffff00;
}
}
Note that these two ways use less memory and more process units .. I don't say this is the best way but its just another approach.
If you use very big enum types then, following can be useful;
public enum deneme {
UPDATE, UPDATE_FAILED;
private static Map<Integer, deneme> ss = new TreeMap<Integer,deneme>();
private static final int START_VALUE = 100;
private int value;
static {
for(int i=0;i<values().length;i++)
{
values()[i].value = START_VALUE + i;
ss.put(values()[i].value, values()[i]);
}
}
public static deneme fromInt(int i) {
return ss.get(i);
}
public int value() {
return value;
}
}
If you want emulate enum of C/C++ (base num and nexts incrementals):
enum ids {
OPEN, CLOSE;
//
private static final int BASE_ORDINAL = 100;
public int getCode() {
return ordinal() + BASE_ORDINAL;
}
};
public class TestEnum {
public static void main (String... args){
for (ids i : new ids[] { ids.OPEN, ids.CLOSE }) {
System.out.println(i.toString() + " " +
i.ordinal() + " " +
i.getCode());
}
}
}
OPEN 0 100
CLOSE 1 101
The ordinal() function returns the relative position of the identifier in the enum. You can use this to obtain automatic indexing with an offset, as with a C-style enum.
Example:
public class TestEnum {
enum ids {
OPEN,
CLOSE,
OTHER;
public final int value = 100 + ordinal();
};
public static void main(String arg[]) {
System.out.println("OPEN: " + ids.OPEN.value);
System.out.println("CLOSE: " + ids.CLOSE.value);
System.out.println("OTHER: " + ids.OTHER.value);
}
};
Gives the output:
OPEN: 100
CLOSE: 101
OTHER: 102
Edit: just realized this is very similar to ggrandes' answer, but I will leave it here because it is very clean and about as close as you can get to a C style enum.
#scottf
An enum is like a Singleton. The JVM creates the instance.
If you would create it by yourself with classes it could be look like that
public static class MyEnum {
final public static MyEnum ONE;
final public static MyEnum TWO;
static {
ONE = new MyEnum("1");
TWO = new MyEnum("2");
}
final String enumValue;
private MyEnum(String value){
enumValue = value;
}
#Override
public String toString(){
return enumValue;
}
}
And could be used like that:
public class HelloWorld{
public static class MyEnum {
final public static MyEnum ONE;
final public static MyEnum TWO;
static {
ONE = new MyEnum("1");
TWO = new MyEnum("2");
}
final String enumValue;
private MyEnum(String value){
enumValue = value;
}
#Override
public String toString(){
return enumValue;
}
}
public static void main(String []args){
System.out.println(MyEnum.ONE);
System.out.println(MyEnum.TWO);
System.out.println(MyEnum.ONE == MyEnum.ONE);
System.out.println("Hello World");
}
}
public class MyClass {
public static void main(String args[]) {
Ids id1 = Ids.OPEN;
System.out.println(id1.getValue());
}
}
enum Ids {
OPEN(100), CLOSE(200);
private final int id;
Ids(int id) { this.id = id; }
public int getValue() { return id; }
}
#scottf, You probably confused because of the constructor defined in the ENUM.
Let me explain that.
When class loader loads enum class, then enum constructor also called. On what!! Yes, It's called on OPEN and close. With what values 100 for OPEN and 200 for close
Can I have different value?
Yes,
public class MyClass {
public static void main(String args[]) {
Ids id1 = Ids.OPEN;
id1.setValue(2);
System.out.println(id1.getValue());
}
}
enum Ids {
OPEN(100), CLOSE(200);
private int id;
Ids(int id) { this.id = id; }
public int getValue() { return id; }
public void setValue(int value) { id = value; }
}
But, It's bad practice. enum is used for representing constants like days of week, colors in rainbow i.e such small group of predefined constants.
I think you're confused from looking at C++ enumerators. Java enumerators are different.
This would be the code if you are used to C/C++ enums:
public class TestEnum {
enum ids {
OPEN,
CLOSE,
OTHER;
public final int value = 100 + ordinal();
};
public static void main(String arg[]) {
System.out.println("OPEN: " + ids.OPEN.value);
System.out.println("CLOSE: " + ids.CLOSE.value);
System.out.println("OTHER: " + ids.OTHER.value);
}
};