2015-01-05 61 views
0

我目前正在運行java 7,我發現java在特定情況下有奇怪的行爲。下面的代碼顯示一個迭代的針對通用特里數據結構中的下一個():Java可選參數不能按預期工作

public final Iterator iterator = new Iterator() 
{ 
    private int objsProcessed = 0; 
    private K currentKeySequence = null; 

    @Override 
    public boolean hasNext() 
    { 
     return objsProcessed < numObjects; 
    } 

    @Override 
    public Object next() 
    { 
     if (keySequences.isEmpty() == false) 
     { 
      currentKeySequence = keySequences.get(objsProcessed); 
     } 
     else 
     { 
      return null; 
     } 
     objsProcessed++; 
     Character[] test=new Character[]{'a','b'}; 
     Object result = reference.get(test); 
     result = reference.get(currentKeySequence); 
     return result; 
    } 

    @Override 
    public void remove() 
    { 
     reference.remove(currentKeySequence); 
    } 
}; 

密鑰序列添加在以下:

public Trie add(V object, K... keySequence) 
{ 
    Node<K, V> currentNode = root; 
    for (int i = 0; i < keySequence.length; i++) 
    { 
     currentNode = currentNode.insert(new Node<K, V>(keySequence[i], 
       currentNode)); 
    } 
    currentNode.addObject(object); 
    keySequences.add((K) keySequence); 
    numObjects++; 
    return this; 
} 

get方法採用可變數目的參數:

public List<V> get(K... keySequence) 
{ 
    Node<K, V> currentNode = root; 
    for (int i = 0; i < keySequence.length; i++) 
    { 
     currentNode = currentNode.getNode(keySequence[i]); 
    } 
    if (currentNode != null) 
     return currentNode.getObjects(); 
    else 
     return null; 
} 

的問題是,當我通過currentKeySequence其是,在我的測試的情況下,一個字符[]大小2的,它使keySequence變量實際上是尺寸1的是CON的陣列保留currentKeySequence而不僅僅是currentKeySequence(大小2)。如果不是currentKeySequence,我會傳遞新的Character [] {'a','b'},它可以按預期工作,而不會將數組放入包裝數組中。

更新: 換句話說,我有currentKeySequence =測試=字符[] {「A」,「B」},其中唯一的區別是currentKeySequence從列表中檢索和VAR測試本地實例化與「新」關鍵字。如果我通過var test,那麼keySequence = Character [] {'a','b'},如果我通過currentKeySequence,那麼keySequence = Object [] {Character [] {'a','b' }}。我知道如果我調用get('a','b'),keySequence將是一個Object [] {'a','b'}。我期望如果參數總是包裝到一個數組中,兩種情況都是一樣的。

我做錯了什麼或者這是一個錯誤?

+0

Var args將是一個包含所有傳遞元素的固定大小的數組。如果你傳遞任何大小的數組,你將得到一個大小爲1的數組。 – AlfredoVR

+0

而你確定* currentKeySequence是'Character []'?什麼'System.out.println(Arrays.deepToString(currentKeySequence))'給你回來? – Makoto

+0

你是怎麼定義'K'的? – GriffeyDog

回答

0

的問題是線 private K currentKeySequence = null;

鉀含量字符但VAR currentKeySequence被分配給字符[](K [])。在調試器中沒有看到任何問題,或者在運行時出現問題,但是當變量作爲參數傳遞時,它以Object [] {Character [] {...}}的形式到達。一旦在當前KeySequence定義中將K改爲K [],該方法就會收到正確的參數(只是Character [] {...});

3

這不是一個錯誤。這就是varags的工作原理。

變量參數(varags)允許您傳入無參數或多個參數。爲了做到這一點,它使用一個數組來跟蹤參數。一個論點不是特別的;它存儲在數組的第一個索引中。

在執行任何操作之前,它總是檢查數組是否包含項目,因爲客戶端可以不指定參數參數。

+0

然後,它們都應該算作一個參數。如果我做Character [] test = new Character [] {'a','b'}; Object result = reference.get(test);它工作正常,但爲什麼與上面的var「test」基本相同的currentKeySequence不起作用?唯一的區別是我從列表中調出它,調試器仍然顯示它爲一個數組,就像「test」 –

+0

@GabrielPiacenti你是什麼意思?變量argumentd作爲數組處理。如果你指定一個數組,那麼將使用該數組。如果不是,將創建一個新的數組,並且您的參數將被存儲在它們中 –

+0

我的意思是currentKeySequence = test = Character [] {'a','b'}唯一的區別是它從列表中檢索。如果我通過測試,然後keySequence = Character [] {'a','b'}如果我通過currentKeySequence然後keySequence =對象[] {字符[] {'a','b'}} –

2

你的可變參數結構正在做它所說的。它將您給它的所有內容封裝到某種類型的數組K中。

如果您通過陣列陣列;也就是說,如果你傳遞了一些可以擴展爲二維數組的東西,那麼可變參數將把它解釋爲可變參數數組的單個參數。

在你的問題,這也將被視爲二維數組:

new Object[]{new Character[]{'a','b'}} 

原因是:它是嵌套在Object[]內部的Character[](這是完全合法的)。

+0

我沒有發送Object [] {new Character [] {'a','b '}},我在一種情況下發送字符[] {'a','b'},該字符正在轉換爲Object [] {new Character [] {'a','b'}}}其他。 –

+0

我在原始問題的評論部分中提供了一些代碼,以證明這種情況。我鼓勵你這樣做。 – Makoto