Como converter resultado seqüência de enumeração com toString substituído (de volta) para enum?
-
04-07-2019 - |
Pergunta
Dado o seguinte java enum:
public enum AgeRange {
A18TO23 {
public String toString() {
return "18 - 23";
}
},
A24TO29 {
public String toString() {
return "24 - 29";
}
},
A30TO35 {
public String toString() {
return "30 - 35";
}
},
}
Existe alguma maneira de converter um valor de seqüência de "18-23"? Ao valor enum correspondente ou seja AgeRange.A18TO23
Obrigado!
Solução
O melhor e mais simples maneira de fazer isso é assim:
public enum AgeRange {
A18TO23 ("18-23"),
A24TO29 ("24-29"),
A30TO35("30-35");
private String value;
AgeRange(String value){
this.value = value;
}
public String toString(){
return value;
}
public static AgeRange getByValue(String value){
for (final AgeRange element : EnumSet.allOf(AgeRange.class)) {
if (element.toString().equals(value)) {
return element;
}
}
return null;
}
}
Em seguida, você só precisa chamar o método getByValue()
com a entrada String
nele.
Outras dicas
Você pode sempre criar um mapa de string para valor - fazê-lo estaticamente, assim você só precisa mapear uma vez, assumindo que a string retornada permanece o mesmo ao longo do tempo. Não há nada de built-in, tanto quanto eu estou ciente.
De acordo com java eficaz (2ª ed) o artigo 30, pode ser (é muito mais rápido do que o loop)
public enum AgeRange {
A18TO23("18-23"),
A24TO29("24-29"),
A30TO35("30-35");
private final String value;
AgeRange(String value){
this.value = value;
}
@Override public String toString(){
return value;
}
private static final Map<String, AgeRange> stringToEnum =
new HashMap<String, AgeRange>();
static {
for (AgeRange r : values()) {
stringToEnum.put(r.toString(), r);
}
}
public static AgeRange getByValue(String value){
return stringToEnum.get(value);
}
}
for (AgeRange ar: EnumSet.allOf(AgeRange)) {
if (ar.toString().equals(inString)) {
myAnswer = ar;
break;
}
}
Ou algo assim? Apenas digitada, não ter executado através de um compilador. Perdoe (comentário sobre) erros de digitação ...
Ou usar a lógica como este para construir um mapa uma vez. Evite iteração em tempo de execução. Boa ideia, Jon.
As substituições de classe "toString ()" - então, para obter a operação inversa, você precisará substituir valueOf()
para traduzir a saída do toString()
volta para os valores Enum
public enum AgeRange {
A18TO23 {
public String toString() {
return "18 - 23";
}
public AgeRange valueOf (Class enumClass, String name) {
return A18T023
}
},
.
.
.
}
Comprador cuidado - uncompiled e não testado ...
O mecanismo para toString()
e valueOf()
é uma parte documentada do API
Você poderia tentar algo como o seguinte?
static AgeRange fromString(String range) {
for (AgeRange ageRange : values()) {
if (range.equals(ageRange.toString())) {
return ageRange;
}
}
return null;
}
Ou, como outros sugeriram, utilizando uma abordagem de cache:
private static Map<String, AgeRange> map;
private static synchronized void registerAgeRange(AgeRange ageRange) {
if (map == null) {
map = new HashMap<String, AgeRange>();
}
map.put(ageRange.toString(), ageRange);
}
AgeRange() {
registerAgeRange(this);
}
static AgeRange fromString(String range) {
return map.get(range);
}