Получение всех имен в перечислении в виде строки[]
каков самый простой и / или самый короткий способ получить имена элементов перечисления в виде массива Strings?
Я имею в виду, что если бы, например, у меня было следующее перечисление:
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
public static String[] names() {
// ...
}
}
the names() метод вернет аналог массива в { "NEW", "RUNNABLE", "BLOCKED", "WAITING", "TIMED_WAITING", "TERMINATED" }.
18 ответов:
обновление:
в java 8 это одна строка для произвольного класса перечисления с использованием потока:
public static String[] getNames(Class<? extends Enum<?>> e) { return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new); }в java 7, немного менее элегантно, но это один лайнер делает трюк:
public static String[] names() { return Arrays.toString(State.values()).replaceAll("^.|.$", "").split(", "); }кроме того, вот версия, которая будет работать для любой перечисление:
public static String[] getNames(Class<? extends Enum<?>> e) { return Arrays.toString(e.getEnumConstants()).replaceAll("^.|.$", "").split(", "); }что вы бы назвали так:
String[] names = getNames(State.class); // any other enum class will work too
создать
String[]массив для имен и вызова статическогоvalues()метод, который возвращает все значения перечисления, затем повторите значения и заполните массив имен.public static String[] names() { State[] states = values(); String[] names = new String[states.length]; for (int i = 0; i < states.length; i++) { names[i] = states[i].name(); } return names; }
Если вы можете использовать Java 8, это прекрасно работает (альтернатива предложению Юры, более эффективная):
public static String[] names() { return Stream.of(State.values()).map(State::name).toArray(String[]::new); }
вот элегантное решение с использованием Apache commons-lang3:
EnumUtils.getEnumList(State.class)хотя он возвращает список, вы можете легко преобразовать список в список.toArray ()
Я бы написал это вот так
public static String[] names() { java.util.LinkedList<String> list = new LinkedList<String>(); for (State s : State.values()) { list.add(s.name()); } return list.toArray(new String[list.size()]); }
что-то вроде этого сделать:
public static String[] names() { String[] names = new String[values().length]; int index = 0; for (State state : values()) { names[index++] = state.name(); } return names; }в документации рекомендуется использовать
toString()вместоname()в большинстве случаев, но вы явно попросили имя здесь.
мое решение, с манипуляцией строк (не самый быстрый, но компактный):
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; public static String[] names() { String valuesStr = Arrays.toString(State.values()); return valuesStr.substring(1, valuesStr.length()-1).replace(" ", "").split(","); } }
другой стороны :
первый
Arrays.asList(FieldType.values()) .stream() .map(f -> f.toString()) .toArray(String[]::new);иначе
Stream.of(FieldType.values()).map(f -> f.toString()).toArray(String[]::new);
Я бы сделал это таким образом (но я бы, вероятно, сделал имена немодифицируемым набором вместо массива):
import java.util.Arrays; enum State { NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED; public static final String[] names=new String[values().length]; static { State[] values=values(); for(int i=0;i<values.length;i++) names[i]=values[i].name(); } } public class So13783295 { public static void main(String[] args) { System.out.println(Arrays.asList(State.names)); } }
у меня есть такая же потребность и использовать общий метод (внутри класса ArrayUtils):
public static <T> String[] toStringArray(T[] array) { String[] result=new String[array.length]; for(int i=0; i<array.length; i++){ result[i]=array[i].toString(); } return result; }и просто определить статический внутри перечисления...
public static final String[] NAMES = ArrayUtils.toStringArray(values());перечисления Java действительно пропускают методы names() и get(index), они действительно полезны.
обычный способ (каламбур):
String[] myStringArray=new String[EMyEnum.values().length]; for(EMyEnum e:EMyEnum.values())myStringArray[e.ordinal()]=e.toString();
Я сделал небольшой тест на решение @Bohemian. Производительность лучше при использовании наивного цикла вместо этого.
public static <T extends Enum<?>> String[] getEnumNames(Class<T> inEnumClass){ T [] values = inEnumClass.getEnumConstants(); int len = values.length; String[] names = new String[len]; for(int i=0;i<values.length;i++){ names[i] = values[i].name(); } return names; } //Bohemian's solution public static String[] getNames(Class<? extends Enum<?>> e) { return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new); }
Если вы хотите самый короткий вы можете попробовать
public static String[] names() { String test = Arrays.toString(values()); return text.substring(1, text.length()-1).split(", "); }
просто мысль: может быть, вам не нужно создавать метод для возврата значений перечисления в виде массива строк.
зачем вам нужен массив строк? Может быть, вам нужно только конвертировать значения, когда вы их используете, если вам когда-нибудь понадобится это сделать.
примеры:
for (State value:values()) { System.out.println(value); // Just print it. }
for (State value:values()) { String x = value.toString(); // Just iterate and do something with x. }
// If you just need to print the values: System.out.println(Arrays.toString(State.values()));
попробуйте это:
public static String[] vratAtributy(){ String[] atributy = new String[values().length]; for(int index = 0; index < atributy.length; index++){ atributy[index] = **values()[index].toString();** } return atributy;
Comments