2010-01-19 83 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