Sovrascrivi valueof () e toString () in enum Java

I valori nel mio enum sono parole che devono avere degli spazi in loro, ma le enumerazioni non possono avere spazi nei loro valori, quindi è tutto ammucchiato. Voglio sovrascrivere toString() per aggiungere questi spazi in cui lo dico.

Voglio anche che l’enum fornisca l’enum corretto quando uso valueOf() sulla stessa stringa a cui ho aggiunto gli spazi.

Per esempio:

 public enum RandomEnum { StartHere, StopHere } 

Chiama toString() su RandomEnum cui valore è StartHere restituisce la stringa "Start Here" . Call valueof() su quella stessa stringa ( "Start Here" ) restituisce il valore enum StartHere .

Come posso fare questo?

Puoi provare questo codice. Poiché non è ansible sovrascrivere il metodo valueOf , è necessario definire un metodo personalizzato ( getEnum nel seguente codice di esempio) che restituisce il valore necessario e modifica il client per utilizzare invece questo metodo.

 public enum RandomEnum { StartHere("Start Here"), StopHere("Stop Here"); private String value; RandomEnum(String value) { this.value = value; } public String getValue() { return value; } @Override public String toString() { return this.getValue(); } public static RandomEnum getEnum(String value) { for(RandomEnum v : values()) if(v.getValue().equalsIgnoreCase(value)) return v; throw new IllegalArgumentException(); } } 

Prova questo, ma non sono sicuro che funzionerà ovunque 🙂

 public enum MyEnum { A("Start There"), B("Start Here"); MyEnum(String name) { try { Field fieldName = getClass().getSuperclass().getDeclaredField("name"); fieldName.setAccessible(true); fieldName.set(this, name); fieldName.setAccessible(false); } catch (Exception e) {} } } 

Che ne dici di un’implementazione di Java 8? (null può essere sostituito dall’Enum predefinito)

 public static RandomEnum getEnum(String value) { List list = Arrays.asList(RandomEnum.values()); return list.stream().filter(m -> m.value.equals(value)).findAny().orElse(null); } 

O potresti usare:

 ...findAny().orElseThrow(NotFoundException::new); 

Puoi usare una mappa statica nel tuo enum che mappa le stringhe in costanti enum. Usalo in un metodo statico ‘getEnum’. Questo salta la necessità di scorrere l’enumerazione ogni volta che si vuole ottenere uno dal suo valore di Stringa.

 public enum RandomEnum { StartHere("Start Here"), StopHere("Stop Here"); private final String strVal; private RandomEnum(String strVal) { this.strVal = strVal; } public static RandomEnum getEnum(String strVal) { if(!strValMap.containsKey(strVal)) { throw new IllegalArgumentException("Unknown String Value: " + strVal); } return strValMap.get(strVal); } private static final Map strValMap; static { final Map tmpMap = Maps.newHashMap(); for(final RandomEnum en : RandomEnum.values()) { tmpMap.put(en.strVal, en); } strValMap = ImmutableMap.copyOf(tmpMap); } @Override public String toString() { return strVal; } } 

Assicurati che l’inizializzazione statica della mappa avvenga sotto la dichiarazione delle costanti enum.

BTW: quel tipo di “ImmutableMap” proviene dall’API di Google guava e lo consiglio vivamente in casi come questo.


MODIFICA – Per i commenti:

  1. Questa soluzione presuppone che ogni valore di stringa assegnato sia univoco e non nullo. Dato che il creatore dell’enum può controllarlo e che la stringa corrisponde al valore enum univoco e non nullo, questa sembra una restrizione sicura.
  2. Ho aggiunto il metodo ‘toSTring ()’ come richiesto nella domanda

Hai ancora un’opzione da implementare nella tua enumerazione:

 public static > T valueOf(Class enumType, String name){...} 

Non penso che la tua intenzione di ottenere valoreOf (“Inizia qui”) per funzionare. Ma per quanto riguarda gli spazi … prova il seguente …

 static private enum RandomEnum { R("Start There"), G("Start Here"); String value; RandomEnum(String s) { value = s; } } System.out.println(RandomEnum.G.value); System.out.println(RandomEnum.valueOf("G").value); Start Here Start Here 

Di seguito è una buona alternativa generica a valueOf ()

 public static RandomEnum getEnum(String value) { for (RandomEnum re : RandomEnum.values()) { if (re.description.compareTo(value) == 0) { return re; } } throw new IllegalArgumentException("Invalid RandomEnum value: " + value); }