2014-11-24 39 views
0

它是什麼歸結到我試圖構建一個基於枚舉數的java.util.ListList<T>,但這裏是catch-我不想第一個值在名單。我提出這樣做​​的方式......呃......這不是一件好事。構建一個列表<T>從枚舉

下面是我使用的代碼:

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

這有效地創建從我的枚舉列表<>,並移除第一個值,然後試圖創建另一個列表與創建的列表。

這實際上可能是正確的做法,但只是看着它尖叫「無效」。我在一個我是其成員的論壇上向幾個人展示了它,他們都說這是多麼醜陋,並且笑了起來;然而,他們中的任何一個都不能提供更好的方式去做。

+3

爲什麼當你已經有一個列表時,你再次創建列表? – 2014-11-24 13:15:34

+2

@JeroenVannevel,因爲Arrays.asList()返回的列表不支持remove()方法。 – 2014-11-24 13:16:31

+0

對此的reasining是因爲我無法弄清楚如何使用remove()函數後返回列表,我試圖在單行返回中完成此操作。我應該可能已經說過了。 #remove返回已刪除的值,所以我在解決如何在單行路徑中解決此問題時遇到問題。 – Hobbyist 2014-11-24 13:18:02

回答

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 <>(Arrays.asList(SlayerTask.values())))remove(0);' – Hobbyist 2014-11-24 13:28:25

+0

@ Christian.tucker移除數組列表的第一個元素強制列表複製所有的元素向左。並不是說它會產生很大的差異,但上面的代碼會更快。 – 2014-11-24 13:34:45

+0

@ Christian.tucker將項目添加到單個列表的for-loop會更快,因爲它避免了用'remove'調用推動項目。雖然這是一個小小的差異。我想知道你爲什麼如此擔心這種表現?如果結果列表稍後未被修改,則可以只創建一次並保留它。如果需要修改,可以將該列表創建爲模板一次,然後使用'new ArrayList <>(template)'創建它的副本。如果每個納秒*真的很重要,則應該使用裸數組而非列表。 – Boann 2014-11-24 13:41:09

3

如何:

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

確實;輕鬆最簡單,最清晰。下跌是第一個不會被收集的因素。 – 2014-11-24 14:11:21

-1

這工作:

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

或Java 8:

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

嗯...沒有太多更好的。

+2

仍然不正確。最後一個參數應該是MyEnum.values()。length(它是唯一的)。它不應該調用values()兩次:每次調用都會返回一個新數組。 – 2014-11-24 13:29:06

+0

@jbn Doh!我認爲這是長度,而不是索引。順便說一句,不是藉口,但我很少有一個編譯器 - 我在手機上編寫代碼,所以我必須記住所有的API,或者如果我有時間瀏覽javadoc。不過,謝謝你撿起來。對values()的雙重調用是保持一行。 – Bohemian 2014-11-24 19:37:06

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 2014-11-24 16:25:14

+0

這兩個都是對的,我的觀點是這個想法。 – 2014-11-25 10:41:12