2014-11-24 3 views
0

Что я имею в виду: я пытаюсь построить List<T> из пакета java.util.List на основе перечислителя, но вот уловка: я не хочу, чтобы первое значение находилось в список. То, как я придумал это ... Ну ... Это не может быть хорошо.Построение списка <T> от Enum

Вот код, я использую:

Arrays.asList(Arrays.asList(MyEnum.values()).remove(0)); 

Это эффективно создает список <> из моего перечисления, и удаляет первое значение, а затем пытается создать еще один список с созданным списком.

Возможно, это действительно правильный способ сделать это, но просто глядя на него, он кричит «Неэффективно». Я показал это нескольким людям на форуме, членом которого я являюсь, и все они сказали, насколько уродливым оно было, и засмеялись; Однако ни один из них не мог/не предоставил бы лучший способ сделать это.

+3

Почему вы создаете список повторно, когда у вас уже есть список? –

+2

@JeroenVannevel, потому что список, возвращаемый Arrays.asList(), не поддерживает метод remove(). –

+0

Реабилитация для этого заключается в том, что я не мог понять, как вернуть список после использования функции remove(), я пытаюсь сделать это все в однострочном возврате. Мне следовало бы это сказать. #remove возвращает значение, которое было удалено, поэтому у меня возникла проблема с выяснением, как это сделать в однострочном пути. – Hobbyist

ответ

3

Я не думаю, что код действительно уродливые или неэффективно. Большая проблема заключается в том, что он не работает, потому что список, возвращаемый Arrays.asList, поддерживается базовым массивом и поэтому имеет фиксированный размер.

Вы можете использовать subList вместо remove, чтобы заставить его работать:

List<MyEnum> list = Arrays.asList(MyEnum.values()); 
list = list.subList(1, list.size()); 

Это означает, что полученный список на самом деле состоит из двух списков объектов (asList и ее subList), которые могут или не могут беспокоить вас , Тем не менее, вы можете создать плоскую ArrayList из полученного списка:

list = new ArrayList<>(list); 

Если вы не хотите минимизировать выделение объекта, петлевые значения и добавить их в один список непосредственно:

MyEnum[] values = MyEnum.values(); 
List<MyEnum> list = new ArrayList<>(values.length - 1); 
for (int i = 1; i < values.length; i++) 
    list.add(values[i]); 
+0

Каким будет сравнение производительности против 'ArrayList list; \t \t \t (list = new ArrayList <> (Arrayys.asList (SlayerTask.values ​​()))). Remove (0); ' – Hobbyist

+0

@ Christian.tucker, удаляющий первый элемент arraylist, заставляет список скопировать все элементов влево. Не то чтобы это имело бы большое значение, но вышеприведенный код был бы быстрее. –

+0

@ Christian.tucker За цикл, который добавляет элементы в один список, будет быстрее, поскольку он избегает перемещать предметы вокруг с помощью вызова 'remove'. Это небольшая разница. Интересно, почему вы так беспокоитесь об этом? Если полученный список не будет изменен позже, вы можете создать его только один раз и сохранить его. Если его нужно изменить, вы можете создать список один раз в качестве шаблона, а затем создать его копии с помощью 'new ArrayList <> (template)'. Если каждый наносекунда действительно имеет значение, вы должны использовать голые массивы, а не списки. – Boann

3

Как насчет:

Arrays.asList(MyEnum.values()).subList(1, MyEnum.values().length); 
+0

Действительно; Легко и просто. Нижняя сторона - это первый элемент, который не будет собран. –

-1

Это будет работа:

List<T> enums = Arrays.asList(Arrays.copyOfRange(MyEnum.values(), 1, MyEnum.values().length - 1)); 

Или ява 8:

Arrays.stream(MyEnum.values()).collect(Collectors.toList()).subList(1, MyEnum.values() - 1); 

Хммм ... не намного лучше.

+2

Все еще неверно. Последним аргументом должен быть MyEnum.values ​​(). Length (it is exclusive). И он не должен вызывать значения() дважды: каждый вызов возвращает новый массив. –

+0

@jbn Doh! Я думал, что это длина, а не индекс. BTW, не оправдание, но у меня редко есть компилятор - я нажимаю код на моем телефоне, поэтому я должен помнить все API-интерфейсы или просматривать javadoc, если у меня есть время. Тем не менее, спасибо, что подобрали его. Двойной вызов значений() заключается в том, чтобы сохранить его в одной строке. – Bohemian

0

Вы уверены, что не можете (не хотите) использовать MyEnum.values ​​и относиться к своему первому элементу по-разному, где он используется?

public enum Enums { 

    first, 
    b, 
    c, 
    d, 
    e, 
    f; 

    public boolean isFirst(Enums e) { 
     return e == first; 
    } 
} 
+0

Вы уверены, что метод не должен быть статическим? Или удалите параметр: 'public boolean isFirst() {return this == first}' – Boann

+0

Оба правильные, моя точка зрения была идеей. –

Смежные вопросы