2010-01-19 116 views
1

我正在實現一個高階拆分函數,該函數需要拆分項的集合,一個定義拆分邊界條件的過濾器委託,以及兩個提供具體實現的委託的ReturnDelegate返回集合的集合類型(所以我不需要在分割函數中修復ArrayList或HashSet,而是將創建返回集合留給調用代碼,從而產生靈活性)。返回是一個Tuple2類,它基本上是兩個異構對象的包裝。Java的泛型問題

這裏的拆分方法:

public static <T, T1 extends Collection<T>, T2 extends Collection<T>> 
    Tuple2<T1, T2> split(final Collection<T> coll, 
         final FilterDelegate<T> filterDelegate, 
         final FilterReturnDelegate<T1> truthyDelegate1, 
         final FilterReturnDelegate<T2> falsyDelegate2) { 
    final Collection<T> t1 = truthyDelegate1.createReturnCollection(); 
    final Collection<T> t2 = falsyDelegate2.createReturnCollection(); 

    for (final T item : coll) { 
     if (filterDelegate.filter(item)) { 
      t1.add(item); 
     } else { 
      t2.add(item); 
     } 
    } 

    final Tuple2<T1, T2> retval = new Tuple2<T1, T2>(); 
    retval.setItem1(t1); 
    retval.setItem2(t2); 

    return retval; 
} 

這裏的Tuple2類。它是異構對象的一個​​簡單的通用感知包裝器。

public final class Tuple2<T1, T2> { 

    private T1 _item1; 

    private T2 _item2; 

    public Tuple2() { 
    } 

    public Tuple2(final T1 item1, final T2 item2) { 
     _item1 = item1; 
     _item2 = item2; 
    } 

    public T1 getItem1() { 
     return _item1; 
    } 

    public T2 getItem2() { 
     return _item2; 
    } 

    public void setItem1(final T1 item1) { 
     _item1 = item1; 
    } 

    public void setItem2(final T2 item2) { 
     _item2 = item2; 
    } 

} 

FilterDelegate:

public interface FilterDelegate<T> { 

    /** 
    * 
    * @param item The item to be filtered. 
    * @return true if the item should be retained. false if the item should be 
    */ 
    boolean filter(T item); 

} 

FilterReturnDelegate:

public interface FilterReturnDelegate<R extends Collection<?>> { 

    R createReturnCollection(); 

} 

然而,上述分割方法甚至不編譯。 Javac正在抱怨

retval.setItems(t1); retval.setItems(t2); 

"The method setItem1(T1) in the type Tuple2<T1,T2> is not applicable for the arguments (Collection<T>)"

想知道我在這裏做錯了什麼?

+0

請考慮使用來自Guava的'Iterables.filter()'(http://guava-libraries.googlecode.com)並跳過處理所有這些。 在你的情況下,你會同時使用'Iterables.filter(c,p)'和'Iterables.filter(c,Predicates.not(p))'來獲得這兩個子集。 – 2010-01-19 21:59:05

回答

3

t1t2T1類型和T2的:

final T1 t1 = truthyDelegate1.createReturnCollection(); 
final T2 t2 = falsyDelegate2.createReturnCollection(); 

Collection<T>不是T1一個亞型,所以setItem(t1)會失敗。

+0

該死......這樣一個愚蠢的錯誤!謝謝! – EnToutCas 2010-01-19 20:39:06