2014-02-16 76 views
-2

我有這樣的方法:奇怪Arrays.asList()行爲

//not related to the error, but included for reference 
ArrayList<ArrayList<Color>> a = new ArrayList<ArrayList<Color>>(); 

void addColorToList(float[] j) //this array always length 3 
{ 
    float[] k = Arrays.copyOf(j, 3); 
    Arrays.sort(k); 
      //Error in the following line 
    a.get(Arrays.asList(j).indexOf(k[0])).add(new Color(j[0], j[1], j[2])); 
} 

與此錯誤:

我已經決定了我的代碼總是調用a.get()爲-1,因爲Arrays.asList(j). indexOf(k[0])做找不到元素。但是,我不明白爲什麼這不起作用,因爲我期望它。我試着打印出Arrays.asList(j)的結果,但我不確定結果如何:[[[email protected]]。有人可以告訴我這是什麼問題嗎?

+0

@OliCharlesworth使用'addColorToList((new Color(r.nextInt()))。getRGBColorComponents(new float [3]));''' r'是一個隨機'對象。另外,我已經打印了'j',關於它並沒有什麼特別之處。 – Azar

回答

2

讓我們開始與此:

I tried printing out the result of Arrays.asList(j), but I'm not really sure what to make of the result: [[[email protected]].

您打印使用(有效)的列表toString()方法。所以...

  • 外面的'['和']'來自列表格式。

  • 您有一個包含一個元素的列表。

  • 該元素是float的數組。 (該[[email protected]Object.toString()製造,[F是怎樣的類型float[]呈現...)


這實際上是一個重要的線索。 Arrays.asList(float [])正在返回「float []列表」...「...

但是爲什麼?

嗯,因爲這就是它應該做的!

Arrays.asList簽名是Arrays.asList<T>(T ...)。這意味着它需要一個明確的T[] ...或一系列零個或多個T實例,然後它將包裝爲Object[]Object[]然後被包裝爲List<Object>(粗略地說)。

這裏關鍵的是,實際類型T 必須是是一個引用類型...不是原始類型。

但是你的代碼似乎期待一個像這樣Arrays.asList(float ...)重載的方法...並期待這會給你你的float[]包裝爲List<Float>

不幸的是,asList沒有這樣的過載。

那麼,什麼是實際發生的情況是:

  • 你的電話綁定到Arrays.asList<float[]>(float[] ...)

  • 的可變參數導致j被包裹在一個陣列;即相當於new float[][]{j}

  • 結果是一個List<float[]> ...的實例...有一個元素。


那麼該如何解決?

一般...

  • 一個解決辦法是代表你的花車爲Float[],而不是float[]。理想情況下,您可以通過首先創建該數組的代碼將此更改返回,等等。

  • 第二個解決方案是在調用asList之前將float[]轉換爲Float[]。簡單的方法是用一個簡單的循環。 (也有可能是第三方庫這樣做)的缺點是:

    • 的轉換需要在每次調用該方法,如果你調用了很多這可能是昂貴的時間發生,

    • 原始數組與您包裝的數組之間沒有連接...如果您想通過列表包裝更新數組。

但在這種情況下,最好的解決辦法是簡單地替換這樣的:用一個簡單的循環

Arrays.asList(j).indexOf(k[0]) 

,超過原來的float[]測試匹配k[0]的條目迭代。


這個故事的寓意:您可以通過在Java中尋求一個優雅的解決方案輕鬆地拍攝自己。

通常,啞代碼更好。 (更快,更正確)

+0

「該元素是一個float數組。」使用該方法時會發生什麼?我之前使用過它,並且感覺它應該返回'List ',而不是'List '。 – Azar

+0

@Azar檢查asList方法簽名。它收到可變數量的類型T並返回一個列表。你傳遞了一個float []類型的參數,所以它返回一個數組列表。 – xp500

+0

@ xp500你說的話似乎是真的。但是,如果是這樣的話,那麼如何從[這個問題] java.util.Arrays.asList(theArray).indexOf(o)'(http://stackoverflow.com/questions/4962361/where-is-javas- array-indexof?lq = 1)工作? – Azar