How to create an ENUM with a "new" value in Java? - java

How I can add new as a value to an enum in Java?
Here's my enum:
public enum AgentProspectStatus
{
loose("loose"),
on_progress("on_progress"),
reached("reached"),
alumni("alumni"),
student("student"),
new("new"); // This throws an error
private String code;
AgentProspectStatus(String code)
{
this.code = code;
}
}
The new("new") line is showing the error:
Unexpected Token

new is keyword in Java. In Java, enums should be spelled in uppercase and case_snake. Changing the case will fix your error.
public enum AgentProspectStatus {
LOOSE("loose"),
ON_PROGRESS("on_progress"),
REACHED("reached"),
ALUMNI("alumni"),
STUDENT("student"),
NEW("new");
private String code;
AgentProspectStatus(String code) {
this.code = code;
}
}

Related

Can I map between values inside enums?

I create enum which has two values: brand name and brand code.
I want to know the brand code by inputting the brand name.
And I also want to know the brand name by inputting the brand code.
Can this problem solved using Enum? or other code is more effective? I want to make the code as shorter as possible
I have created following code to search the code of a brand. If I want to do vice versa, I can create another Hashmap and method to convert the code into a brand. But is that the effective way to solve it?
public enum Brand{
COLA("cola", "CL8935"),
BREAD("bread", "BR2810"),
SNICKERS("snickers", "SN4423");
private static final Map<String, String> BY_BRAND = new HashMap<>();
static {
for (Brand brand : values()){
BY_BRAND.put(brand.code, brand.brand);
}
}
private final String brand;
private final String code;
public static String convertToCode(String brand){
return BY_BRAND.get(brand.toLowerCase()).toString();
}
}
Update - Adding the full enum (with imports)
import java.util.Arrays;
import java.util.function.Function;
enum Brand {
COLA("cola", "CL8935"),
BREAD("bread", "BR2810"),
SNICKERS("snickers", "SN4423");
private final String brand;
private final String code;
Brand(String brand, String code) {
this.brand = brand;
this.code = code;
}
public static Brand findBy(String value, Function<Brand, String> extractor) {
return Arrays.stream(Brand.values())
.filter(brand -> extractor.apply(brand).equalsIgnoreCase(value))
.findFirst()
.orElse("Either a default or throw exception here");
}
public String getBrand() {
return brand;
}
public String getCode() {
return code;
}
}
Original
You could use a static findBy method as an alternative to the map. This would allow you to pass in the value and method reference for the getter which will be used to compare the values stored within the enum.
The difference here would be performance (as maps would be faster), the fact that you would be returning the enum and that you most likely would want either a default enum value or to throw an exception on no matched being found. Below is an example
public static Brand findBy(String value, Function<Brand, String> extractor) {
return Arrays.stream(Brand.values())
.filter(brand -> extractor.apply(brand).equalsIgnoreCase(value))
.findFirst()
.orElse("Either a default or throw exception here");
}
And this can be called like this
public static void main(String[] args) {
Brand brand1 = Brand.findBy("cola", Brand::getBrand);
Brand brand2 = Brand.findBy("BR2810", Brand::getCode);
}
Simple static method in Brand should do:
public static String getBrand(String code) {
for(Brand b : Brand.values()){
if(b.getCode().equals(code)) return b.getBrand();
}
return null;
}
Similarly you can write a getCode(String brand)
Edit: assuming the two attributes do not have the same value, you can check do the bi-di mapping in the same method:
public static String getOtherAttribute(String value) {
for(Brand b : Brand.values()){
if(b.getCode().equals(value)) return b.getBrand();
if(b.getBrand().equals(value)) return b.getCode();
}
return null;
}
If the two attributes may have the same value you can add an argument (flag) to the method's signature to tell which attribute you want to retrieve.

Can't access enum values inside Switch Case / Java

I can't access my enum variables in my switch-case statement:
public enum Country {
FRANCE(0, "France"), SPAIN(1, "Spain");
private final int code;
private final String name;
Country(int code, String name) {
// TODO Auto-generated constructor stub
this.code = code;
this.name = name;
}
public int getCode() {
return code;
}
public String getName() {
return name;
}
}
In another class there is this code :
public Drawable getFlag(){
Drawable d = null;
switch(country_id){
case Country.FRANCE.getCode():
break;
}
return d;
}
But the problem is that when i type Country, there is only class or this.
The expressions in the case statements must be constant values.
One (commonly used) way to approach your problem is by creating a function that gets the enum from the numeric code:
public enum Country {
...
public static Country getCountry(int countryCode) {
for(Country country : Country.values()) {
if(country.code == countryCode) {
return country;
}
}
throw new IllegalArgumentException();
}
Then you'll be able to do the switch on the enum:
switch(Country.getCountry(country_id)){
case Country.FRANCE:
break;
...
}
case labels in a switch statement need be constants
The case expressions must be compile time constant expressions. Your enum instance's variables are constants, but not compile time constants.
We call a variable, of primitive type or type String, that is final
and initialized with a compile-time constant expression (§15.28) a
constant variable. Whether a variable is a constant variable or not
may have implications with respect to class initialization (§12.4.1),
binary compatibility (§13.1, §13.4.9) and definite assignment (§16).

Print Java enum to lower case by default keeping enum constants in uppercase

I have an enum in Java I'd like to serialize, so that when I call it from anywhere in the code, I get the lowercase representation of the name.
Let's say I have the following enum:
public enum Status {
DRAFT, PENDING, COMPLETE;
}
println ("Status=" + Status.DRAFT);
I'd like to get the following:
Status=draft
[Note]: I want to use the enum constants in uppercase, and when requesting the value get the lowercase representation.
I am replying this question myself as i found the solution interesting and could not find a reply in the site. Just in case somebody else looks for a way to solve this.
The solution is simple, just override the Enum toString method like this:
public enum Status {
DRAFT, PENDING, COMPLETE;
#Override
public String toString() {
return name().toLowerCase();
}
}
println ("Status=" + Status.DRAFT);
This would output the name in lower case.
Another solution could be:
public enum Status {
DRAFT, PENDING, COMPLETE;
public String nameLowerCase(){
return name().toLowerCase();
}
}
If you want lower case, you could just use lower case, or mixed case, or whatever makes more sense to you.
public enum Status {
draft, pending, complete;
}
println ("Status=" + Status.draft);
prints
Status=draft
You can use the following Enum class which contains constructor with name and ordinal for each enum constant. You can assign values you need for the enum constant.
public enum Status {
DRAFT(0,"draft"), PENDING(1,"pending"), COMPLETE(2,"complete");
private int key;
private String value;
Status(int key, String value){
this.key = key;
this.value = value;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#Override
public String toString(){
return this.value;
}
}
Since we override the toString method, the value which is lowercase is returned.
Using
System.out.print("Status = "+Status.DRAFT);
would print,
Status = draft
and
System.out.print("Status = "+Status.DRAFT.name());
would print
Status = DRAFT

error code representation using enum in java

I have a bunch of error codes being returned to me by the server. Based on these error codes I need to write some logic for each error code. I don't want to place the plain error in my function. What is the best way to represent these error codes?
I am using an enum for now,
private enum LoginErrorCode{
EMAIL_OR_PASSWORD_INCORRECT("101"),
EMAIL_INCORRECT("102");
private final String code;
LoginErrorCode(String code){
this.code=code;
}
public String getCode(){
return code;
}
}
But I do not know how to handle it if I get an error code unknown to me. Please let me know.
Here is the solution using your Enum that I typically employ to deal with error codes as you have explained in your scenario:
import java.util.HashMap;
import java.util.Map;
public class EnumSample {
public static enum LoginErrorCode {
EMAIL_OR_PASSWORD_INCORRECT("101"), EMAIL_INCORRECT("102"), UNKNOWN_ERROR_CODE("---");
private static Map<String, LoginErrorCode> codeToEnumMap;
private final String code;
LoginErrorCode(String code) {
this.code = code;
}
public String getCode() {
return code;
}
/**
* Looks up enum based on code. If code was not registered as enum, it returns UNKNOWN_ERROR_CODE
* #param code
* #return
*/
public static LoginErrorCode fromCode(String code) {
// Keep a hashmap of mapping between code and corresponding enum as a cache. We need to initialize it only once
if (codeToEnumMap == null) {
codeToEnumMap = new HashMap<String, EnumSample.LoginErrorCode>();
for (LoginErrorCode aEnum : LoginErrorCode.values()) {
codeToEnumMap.put(aEnum.getCode(), aEnum);
}
}
LoginErrorCode enumForGivenCode = codeToEnumMap.get(code);
if (enumForGivenCode == null) {
enumForGivenCode = UNKNOWN_ERROR_CODE;
}
return enumForGivenCode;
}
}
public static void main(String[] args) {
System.out.println( LoginErrorCode.fromCode("101")); //Prints EMAIL_OR_PASSWORD_INCORRECT
System.out.println( LoginErrorCode.fromCode("102")); //Prints EMAIL_INCORRECT
System.out.println( LoginErrorCode.fromCode("999")); //Prints UNKWNOWN_ERROR_CODE
}
}
The point of an enum is that there are no invalid values; invalid values do not exist. There can't be an LoginErrorCode.EMAIL_ERROR_DOES_NOT_EXIST value. You shouldn't have to deal with a non-existent value. That is what makes an enum the best representation, because you have a known set of values to represent.
EDIT
Since you need to translate the error code strings to your enum, include a Map of the error code Strings to your enum values:
public enum LoginErrorCode
{
EMAIL_OR_PASSWORD_INCORRECT,
EMAIL_INCORRECT;
private static Map<String, LoginErrorCode> map;
// static initializer
static {
map = new HashMap<String, LoginErrorCode>();
map.put("101", EMAIL_OR_PASSWORD_INCORRECT);
map.put("102", EMAIL_INCORRECT);
}
public static LoginErrorCode fromCode(String code)
{
return map.get(code);
}
}
The fromCode method will return null on an invalid code.

enum type with numeric constant

I'm getting data from a legacy system where a certain one byte field is a code that may contain a letter or a number. I want to map it to an enum but I'm not sure how to handle the numeric values.
public enum UsageCode {
A ("Antique"),
F ("Flood Damaged"),
N ("New");
// 0 ("Unknown") How to allow for value of "0"?
private final String description;
UsageCode(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
Turn it inside out:
public enum UsageCode {
ANTIQUE ('A'),
FLOOD_DAMAGED ('F'),
NEW ('N');
UNKNOWN ('0')
private static final Map<Character, UsageCode> charToEnum
= new HashMap<Character, UsageCode>();
static { // Initialize map from legacy code to enum constant
for (UsageCode code : values())
charToEnum.put(code.getCode(), code);
}
// Returns UsageCode for legacy character code, or null if code is invalid
public static UsageCode fromLegacyCode(char code) {
return charToEnum.get(code);
}
private final char code;
UsageCode(char code) {
this.code = code;
}
public char getCode() {
return code;
}
}
For converting the incoming character codes into enum values, I added an inner Map<Character, UsageCode> and a static conversion method.
Example adapted from Effective Java 2nd Edition, Item 30.
You can do it other way round, having a meaningful constant and storing legacy value representation:
public enum UsageCode {
ANTIQUE("A"),
FLOOD_DAMAGED("F"),
NEW("N"),
UNKNOWN("0");
private String legacy;
private UsageCode(String legacy) {
this.legacy = legacy;
}
public static UsageCode toUsageCode(String legacyOutput) {
for(UsageCode code : values()) {
if (code.legacy.equals(legacyOutput)) {
return code;
}
}
return null;
}
}

Categories

Resources