posicion - encontrar palabras en un string java
¿Cómo puedo buscar una enumeración de Java a partir de su valor de cadena? (10)
Me gustaría buscar una enumeración a partir de su valor de cadena (o posiblemente cualquier otro valor). He intentado con el siguiente código, pero no permite la estática en los inicializadores. ¿Hay una manera simple?
public enum Verbosity {
BRIEF, NORMAL, FULL;
private static Map<String, Verbosity> stringMap = new HashMap<String, Verbosity>();
private Verbosity() {
stringMap.put(this.toString(), this);
}
public static Verbosity getVerbosity(String key) {
return stringMap.get(key);
}
};
¡En la Especificación del lenguaje Java 7 hay docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#d5e12267 ! que refleja su pregunta sobre la inicialización del mapa con autorreferencias.
¿Y no puedes usar valueOf() ?
Editar: Por cierto, no hay nada que te impida usar static {} en una enumeración.
En caso de que ayude a otros, la opción que prefiero, que no figura aquí, usa la funcionalidad de Guava''s Maps :
public enum Vebosity {
BRIEF("BRIEF"),
NORMAL("NORMAL"),
FULL("FULL");
private String value;
private Verbosity(final String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
private static ImmutableMap<String, Verbosity> reverseLookup =
Maps.uniqueIndex(Arrays.asList(Verbosity.values)), Verbosity::getValue);
public static Verbosity fromString(final String id) {
return reverseLookup.getOrDefault(id, NORMAL);
}
}
Con el valor predeterminado puede usar null
, puede throw IllegalArgumentException
o su fromString
podría devolver un Optional
, sea cual sea el comportamiento que prefiera.
Estás cerca. Para valores arbitrarios, pruebe algo como lo siguiente:
public enum Day {
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
// Reverse-lookup map for getting a day from an abbreviation
private static final Map<String, Day> lookup = new HashMap<String, Day>();
static {
for (Day d : Day.values()) {
lookup.put(d.getAbbreviation(), d);
}
}
private Day(String abbreviation) {
this.abbreviation = abbreviation;
}
public String getAbbreviation() {
return abbreviation;
}
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
}
}
La respuesta de @Lyle es bastante peligrosa y he visto que no funciona particularmente si haces que la enumeración sea una clase interna estática. En su lugar, he usado algo como esto que cargará los mapas de BootstrapSingleton antes de las enumeraciones.
Editar esto ya no debería ser un problema con las JVM modernas (JVM 1.6 o superior), pero creo que todavía hay problemas con JRebel, pero no he tenido la oportunidad de volver a probarlo .
Cargarme primero:
public final class BootstrapSingleton {
// Reverse-lookup map for getting a day from an abbreviation
public static final Map<String, Day> lookup = new HashMap<String, Day>();
}
Ahora cárgalo en el constructor enum:
public enum Day {
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
private Day(String abbreviation) {
this.abbreviation = abbreviation;
BootstrapSingleton.lookup.put(abbreviation, this);
}
public String getAbbreviation() {
return abbreviation;
}
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
}
}
Si tiene una enumeración interna, puede definir el Mapa sobre la definición de enum y eso (en teoría) debería cargarse antes.
Puede usar la función Enum::valueOf()
tal como lo sugirieron Gareth Davis y Brad Mace anteriormente, pero asegúrese de manejar la IllegalArgumentException
que se lanzaría si la cadena utilizada no está presente en la enumeración.
Tal vez, eche un vistazo a esto. Funciona para mí. El propósito de esto es buscar ''ROJO'' con ''/ color_rojo''. Declarar un static map
y cargar las enum
en él solo una vez aportaría algunos beneficios de rendimiento si las enum
son muchas.
public class Mapper {
public enum Maps {
COLOR_RED("/red_color", "RED");
private final String code;
private final String description;
private static Map<String, String> mMap;
private Maps(String code, String description) {
this.code = code;
this.description = description;
}
public String getCode() {
return name();
}
public String getDescription() {
return description;
}
public String getName() {
return name();
}
public static String getColorName(String uri) {
if (mMap == null) {
initializeMapping();
}
if (mMap.containsKey(uri)) {
return mMap.get(uri);
}
return null;
}
private static void initializeMapping() {
mMap = new HashMap<String, String>();
for (Maps s : Maps.values()) {
mMap.put(s.code, s.description);
}
}
}
}
Por favor ponga sus opiniones.
Use el método valueOf
que se crea automáticamente para cada Enum.
Verbosity.valueOf("BRIEF") == Verbosity.BRIEF
Para valores arbitrarios, comience con:
public static Verbosity findByAbbr(String abbr){
for(Verbosity v : values()){
if( v.abbr().equals(abbr)){
return v;
}
}
return null;
}
Solo muévase más tarde a la implementación del mapa si su generador de perfiles se lo indica.
Sé que está iterando sobre todos los valores, pero con solo 3 valores de enumeración, no vale la pena ningún otro esfuerzo, de hecho, a menos que tengas muchos valores, no me molestaría en un Mapa, será lo suficientemente rápido.
con Java 8 puedes lograrlo de esta manera:
public static Verbosity findByAbbr(final String abbr){
return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}
Puedes definir tu Enum como el siguiente código:
public enum Verbosity
{
BRIEF, NORMAL, FULL, ACTION_NOT_VALID;
private int value;
public int getValue()
{
return this.value;
}
public static final Verbosity getVerbosityByValue(int value)
{
for(Verbosity verbosity : Verbosity.values())
{
if(verbosity.getValue() == value)
return verbosity ;
}
return ACTION_NOT_VALID;
}
@Override
public String toString()
{
return ((Integer)this.getValue()).toString();
}
};