Dus*_*etz 0 java generics collections contravariance
请考虑以下代码:
ICondition searchCondition, scopeCondition...
List<ICondition> filtered = CollectionUtil.filter(
Arrays.asList(searchCondition, scopeCondition),
CollectionUtil.isNonNull);
Run Code Online (Sandbox Code Playgroud)
它无法编译:
"该
filter(Collection<T>, CollectionUtil.Predicate<T>)类型的方法CollectionUtil不适用于参数(List<ICondition>, CollectionUtil.Predicate<Object>)"
如果我定义一个ICondition特定的isNonNull()谓词,一切都很好,但这是愚蠢的,我不明白什么是错的或如何解决它.
这是我的实用功能:
public interface Predicate<T>
{
boolean apply(T type);
}
public static <T> List<T> filter(Collection<T> target, Predicate<T> predicate)
{
target = Collections.unmodifiableCollection(target);
List<T> result = new ArrayList<T>();
for (T element: target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
// This predicate works as expected.
public static CollectionUtil.Predicate<String> isStringNonBlank = new CollectionUtil.Predicate<String>() {
public boolean apply (String item) {
return !StringUtils.isBlank(item);
}
};
// This predicate looks fine, but fails in usage.
public static CollectionUtil.Predicate<Object> isNonNull = new CollectionUtil.Predicate<Object>() {
public boolean apply (Object item) {
return null != item;
}
};
Run Code Online (Sandbox Code Playgroud)
为什么我不能使用第二个谓词filter()?
看起来你的filter函数的predicate参数不是正确的逆变.尝试重写如下:
public static <T> List<T> filter(Collection<? extends T> source,
Predicate<? super T> predicate)
{
final List<T> result = new ArrayList<T>(source.size());
for (T element: source)
if (predicate.apply(element))
result.add(element);
return result;
}
Run Code Online (Sandbox Code Playgroud)
这就是说,只要谓词函数愿意接受一个不比类型更窄的类型T,用类型实例T(或者某种类型进一步派生T)调用它就可以正常工作.
| 归档时间: |
|
| 查看次数: |
2927 次 |
| 最近记录: |