Given a string i want to get the enum equivalent of it in constant time.
I have a enum defined like the one shown in the question. Best way to create enum of strings?
public enum Strings {
STRING_ONE("ONE"),
STRING_TWO("TWO")
;
private final String text;
/**
* #param text
*/
private Strings(final String text) {
this.text = text;
}
/* (non-Javadoc)
* #see java.lang.Enum#toString()
*/
#Override
public String toString() {
return text;
}
}
If i now get a string (say "TWO"), is there a way to see if it exists and if it exists then is there a way i can define a method that will return the enum value (for example if i pass "TWO", i should be getting back "Strings.STRING_TWO"?
Is Enum.valueOf() not sufficient? How would you imagine being more efficient than that? There's (usually) no need to have an enum STRING_ONE("ONE") - just call enum value ONE and you get .valueOf() lookup for free.
Otherwise, just create a private static Map<String, YourEnum> and provide a similar valueOf() method that looks up against the Map.
Since Enum.valueOf operates on the built-in name of the enum (i.e. "STRING_ONE" and "STRING_TWO") you would need to roll your own "registry" of name-to-enum, like this:
public enum Strings {
STRING_ONE("ONE"),
STRING_TWO("TWO")
;
private static final Map<String,Strings> byName = new HashMap<String,Strings>();
private final String text;
private Strings(final String text) {
this.text = text;
}
static {
for (Strings s : Strings.values()) {
byName.put(s.toString(), s);
}
}
#Override
public String toString() {
return text;
}
public static Strings forName(String name) {
return byName.get(name);
}
}
Demo.
Above, a map from string name to enum Strings is used to do the translation. If the name is not there, null would be returned from the Strings.forName method.
I think you need to change the code to be :
public enum Strings {
STRING_ONE("ONE"), STRING_TWO("TWO");
private String text;
/**
* #param text
*/
private Strings(final String text) {
this.text = text;
}
public String getText() {
return this.text;
}
public static Strings getByTextValue(String text) {
for (Strings str : Strings.values()) {
if (str.getText().equals(text)) {
return str;
}
}
return null;
}
/*
* (non-Javadoc)
*
* #see java.lang.Enum#toString()
*/
#Override
public String toString() {
return text;
}
}
Example :
String test = "ONE";
Strings testEnum = Strings.getByTextValue(test);
now you have testEnum which is enum reference
Related
I have a String object: String theLanguage = "de";
I have these Two Enums:-
Enum 1:
public enum Lang
{
French("fr"),
German("de"),
English("en"),
Italian("it"),
Spanish("sp");
private String lang;
Lang(String lang) {
this.lang = lang;
}
public String lang() {
return lang;
}
}
and Enum 2:
public enum Lang
{
French(1, "fr"),
German(2, "de"),
English(3, "en"),
Italian(4, "it"),
Spanish(5, "sp");
final int languageID;
private final String code;
Lang( int languageID, String code)
{
this.languageID = languageID;
this.code= code;
}
}
------------------------ My Question -----------------------------
Q 1- What is the Difference between these two Enums ( Basically in 2nd Enum, why there are int values) ?
Q 2- What I need to Do OR Add in 2nd Enum in Order to Search/Match the theLanguage object with Enum2. ?
1 - The second one can be searched for through both the string and int value (if for example you know the id of the language but not its code). Idk what "WhoisRIR" is doing in the place where your constructor should be.
2 - You need to add a getter for the code string and then foreach the enum until you find a element with code identical to theLanguage.
the 2nd just has an extra parameter, the languageID
Add this code to 2nd Enum in order to search by code (e.g "de")
private static Map<String, Lang> reverseLookup = Arrays.stream(values())
.collect(Collectors.toMap(Lang::getCode, Function.identity()));
public String getCode() {
return code;
}
public static Lang fromCode(final String code) {
return reverseLookup.get(code);
}
This question already has answers here:
Java enum elements with spaces?
(8 answers)
Closed 6 years ago.
I need to make an Enum containing some strings with spaces and their values in int like:
public enum status{
Active(1),
Inactive(2);
}
because I am using it with hibernate and also will convert it to JSON for alpaca js forms.
like:
[{"text": "Inactive", "value":"2"},{"text": "Active", "value":"1"}]
I'm stuck in making enum. how to make such type of enum?
You can not put space between strings. Instead of the you can use underscore as follows:
In_Active
You can use this way:
enum Status {
ACTIVE("Active", 1), IN_ACTIVE("In Active", 2);
private final String key;
private final Integer value;
Status(String key, Integer value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public Integer getValue() {
return value;
}
}
You can hold multiple values in one enum and even have getters to handle them. Here is an example I used once (I try to adapt it to your problem):
public enum Status{
ACTIVE(1, "Active"),
INACTIVE(2, "In Active");
private final Integer value;
private final String text;
/**
* A mapping between the integer code and its corresponding text to facilitate lookup by code.
*/
private static Map<Integer, Status> valueToTextMapping;
private Status(Integer value, String text){
this.value = value;
this.text = text;
}
public static Status getStatus(Integer i){
if(valueToTextMapping == null){
initMapping();
}
return valueToTextMapping.get(i);
}
private static void initMapping(){
valueToTextMapping = new HashMap<>();
for(Status s : values()){
valueToTextMapping.put(s.value, s);
}
}
public Integer getValue(){
return value;
}
public String getText(){
return text;
}
#Override
public String toString(){
final StringBuilder sb = new StringBuilder();
sb.append("Status");
sb.append("{value=").append(value);
sb.append(", text='").append(text).append('\'')
sb.append('}');
return sb.toString();
}
}
So in your code you can simply use Status.ACTIVE and it will represent an instance of your Enum, that holds value and text the way you want it
You can't put a space in the middle of an identifier.
Check out this link Is it possible to assign numeric value to an enum in Java? for assigning the value to an enum in java.
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)
What is the best way to have a enum type represent a set of strings?
I tried this:
enum Strings{
STRING_ONE("ONE"), STRING_TWO("TWO")
}
How can I then use them as Strings?
I don't know what you want to do, but this is how I actually translated your example code....
package test;
/**
* #author The Elite Gentleman
*
*/
public enum Strings {
STRING_ONE("ONE"),
STRING_TWO("TWO")
;
private final String text;
/**
* #param text
*/
Strings(final String text) {
this.text = text;
}
/* (non-Javadoc)
* #see java.lang.Enum#toString()
*/
#Override
public String toString() {
return text;
}
}
Alternatively, you can create a getter method for text.
You can now do Strings.STRING_ONE.toString();
Custom String Values for Enum
from http://javahowto.blogspot.com/2006/10/custom-string-values-for-enum.html
The default string value for java enum is its face value, or the element name. However, you can customize the string value by overriding toString() method. For example,
public enum MyType {
ONE {
public String toString() {
return "this is one";
}
},
TWO {
public String toString() {
return "this is two";
}
}
}
Running the following test code will produce this:
public class EnumTest {
public static void main(String[] args) {
System.out.println(MyType.ONE);
System.out.println(MyType.TWO);
}
}
this is one
this is two
Use its name() method:
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(Strings.ONE.name());
}
}
enum Strings {
ONE, TWO, THREE
}
yields ONE.
Either set the enum name to be the same as the string you want or, more generally,you can associate arbitrary attributes with your enum values:
enum Strings {
STRING_ONE("ONE"), STRING_TWO("TWO");
private final String stringValue;
Strings(final String s) { stringValue = s; }
public String toString() { return stringValue; }
// further methods, attributes, etc.
}
It's important to have the constants at the top, and the methods/attributes at the bottom.
Depending on what you mean by "use them as Strings", you might not want to use an enum here. In most cases, the solution proposed by The Elite Gentleman will allow you to use them through their toString-methods, e.g. in System.out.println(STRING_ONE) or String s = "Hello "+STRING_TWO, but when you really need Strings (e.g. STRING_ONE.toLowerCase()), you might prefer defining them as constants:
public interface Strings{
public static final String STRING_ONE = "ONE";
public static final String STRING_TWO = "TWO";
}
You can use that for string Enum
public enum EnumTest {
NAME_ONE("Name 1"),
NAME_TWO("Name 2");
private final String name;
/**
* #param name
*/
private EnumTest(final String name) {
this.name = name;
}
public String getName() {
return name;
}
}
And call from main method
public class Test {
public static void main (String args[]){
System.out.println(EnumTest.NAME_ONE.getName());
System.out.println(EnumTest.NAME_TWO.getName());
}
}
If you do not want to use constructors, and you want to have a special name for the method, try it this:
public enum MyType {
ONE {
public String getDescription() {
return "this is one";
}
},
TWO {
public String getDescription() {
return "this is two";
}
};
public abstract String getDescription();
}
I suspect that this is the quickest solution. There is no need to use variables final.
Get and set with default values.
public enum Status {
STATUS_A("Status A"), STATUS_B("Status B"),
private String status;
Status(String status) {
this.status = status;
}
public String getStatus() {
return status;
}
}
I want to improve my use of JDK 1.5 and stop using private static final String instead of enum. This is what seems to be recommended.
But now my constant class looks like this :
public class CEnum{
/**
* #author JJA
* date : 20/10/2010
*/
public enum ListTypeAffichage {
DEP("DEPOT_TVA"), PAD("PAS_DEPOT_TVA"), NORM("CAT_NORMALE"), CAP("CAT_PARTICULIERE"), CAA("CAT_AUTRE_CAS");
private final String sName;
/**
* #param name String
*/
ListTypeAffichage(String name) {
this.sName = name;
}
/**
* #return String
*/
public String getType() {
return sName;
}
}
/**
* #author JJA
* date : 20/10/2010
*/
public enum ListTypeCategorie {
DEDUIRE("SOMME_A_DEDUIRE"), AJOUTER("SOMME_A_AJOUTER");
private final String sName;
/**
* #param name String
*/
ListTypeCategorie(String name) {
this.sName = name;
}
/**
* #return String
*/
public String getType() {
return sName;
}
}
/**
* #author JJA
* date : 26/10/2010
*/
public enum ListInterval {
POS("POSITIF"), NS("NON_SIGNE");
private final String sName;
/**
* #param name String
*/
ListInterval(String name) {
this.sName = name;
}
/**
* #return String
*/
public String getInterval() {
return sName;
}
}
}
instead of
public class ConstantesADMD {
public static final List<String> typeAffich = new ArrayList<String>();
...
ConstantesADMD(){
typeAffich.add("DEPOT_TVA");
typeAffich.add("PAS_DEPOT_TVA");
typeAffich.add("CAT_NORMALE");
...
}
}
My code seems to be really bad, but at least works. For each enum I have to add the redundant code :
private final String sName;
/**
* #param name String
*/
ListTypeAffichage(String name) {
this.sName = name;
}
/**
* #return String
*/
public String getType() {
return sName;
}
What improvment do you advise me?
Note : forget the last sentences of my first question, I need the index. Tell me if I have to post another question, editing my fisrt seems easier.
I would name my enum-constants as you have named your strings. You can then access the name using the Enum.toString() method. For example:
public enum ListTypeAffichage {
DEPOT_TVA, PAS_DEPOT_TVA, CAT_NORMALE, CAT_PARTICULIERE, CAT_AUTRE_CAS;
/**
* #return String
*/
public String getType() {
return toString();
}
}
You could of course also skip the getType() all together, and access the "type" using toString() instead:
ListTypeAffichage myEnum = ListTypeAffichage.CAT_PARTICULIRE;
System.out.println("Type: " + myEnum.toString()); // like this...
System.out.println("Type: " + myEnum); // ...or like this
According to the API, this is better than using the Enum.name() directly:
public final String name()
[...] Most programmers should use the toString() method in preference to this one [...]
Each enum has a name() method which return the exact string represantation of the constant. So you may do this:
public enum ListTypeAffichage {
DEPOT_TVA, PAS_DEPOT_TVA, CAT_NORMALE, CAT_PARTICULIERE, CAT_AUTRE_CAS
}
and then
ListTypeAffichage.DEPOT_TVA.name();
By using the abbreviations (DEP, PAD, NORM) etc. you have created aliases to (DEPOT_TVA, PAS_DEPOT_TVA, CAT_NORMALE) etc.
If you want to keep the abbreviations, then you'll have to maintain the enum as you have it.
If you are willing to do away with the abbreviations, then you can change you enum as below, I have included a main method in the enum to demonstrate its use.
public enum ListTypeAffichageNames {
DEPOT_TVA,
PAS_DEPOT_TVA,
CAT_NORMALE,
CAT_PARTICULIERE,
CAT_AUTRE_CAS;
public static void main(String[] args) {
System.out.println(DEPOT_TVA.toString());
ListTypeAffichageNames affichage = ListTypeAffichageNames.valueOf("DEPOT_TVA");
System.out.println(affichage.toString());
}
}
In addition to this, your current structure of constants does not give you compile time type checking, and does not prevent something like the following happening during runtime:
ConstantesADMD.typeAffich.clear();
// or
ConstantesADMD.typeAffich.remove("DEPOT_TVA");
ConstantesADMD.typeAffich.add("dEpOt-tVa");