Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 泛型:筛选集合<;T>;但同时也限制了它的随机访问_Java_Generics_Type Inference - Fatal编程技术网

Java 泛型:筛选集合<;T>;但同时也限制了它的随机访问

Java 泛型:筛选集合<;T>;但同时也限制了它的随机访问,java,generics,type-inference,Java,Generics,Type Inference,假设我想要这样一种方法: private static <T> Collection<T> filter(Collection<T> initial, Predicate<T> predicate){ //.... } 这对声明有效,但对调用方无效。即: filter(List.of(1,2,3), x -> x > 1); // fails 我觉得有点尴尬的是,如果我删除&RandomAccess部分,编译(以及T的解析)

假设我想要这样一种方法:

private static <T> Collection<T> filter(Collection<T> initial, Predicate<T> predicate){
    //....
}
这对声明有效,但对调用方无效。即:

filter(List.of(1,2,3), x -> x > 1); // fails
我觉得有点尴尬的是,如果我删除
&RandomAccess
部分,编译(以及
T
的解析)会起作用:

private static <T, M extends Collection<T>> Collection<T> filter(M initial, Predicate<T> predicate){
    ....
} 
私有静态集合筛选器(M初始值,谓词){
....
} 
如果
RandomAccess
采用类型参数,我会理解是否会发生故障。但是它没有,所以(至少在我的理解中)它不应该影响
T
的分辨率

有没有一种方法可以有这样的编译时约束

如果RandomAccess使用类型参数,我会理解是否会发生故障。但是它没有,所以(至少在我的理解中)它不应该影响T的分辨率

事实并非如此。
过滤器的问题(列表(1,2,3),x->x>1)
表示表达式的静态类型
列表。of(1,2,3)
不是
RandomAccess
的子类型,该表达式被拒绝,因为它不满足
扩展RandomAccess
约束

以下两种方法都可以毫无问题地编译,
T
的推断不受影响

filter(new ArrayList<>(List.of(1, 2, 3)), x -> x > 1);
filter(new ArrayList<>(List.of("a", "b", "c")), x -> x.length() > 1);
filter(新的数组列表(1,2,3的列表)),x->x>1;
过滤器(新的数组列表(“a”、“b”、“c”)的列表),x->x.length()>1;

因为
ArrayList
既是
集合
又是
随机访问
子类型。然而,我猜想,根据编译器实现的不同,您可能会遇到多种类型的无用错误消息(例如,
类型Main中的方法过滤器(M,谓词)不适用于
过滤器(…)上的参数(List)
类型不匹配:
列表(…)上的
无法从List转换为M
在Eclipse中)

过滤器((收集和随机访问)列表(1,2,3),x->x>1)有效,仅供参考。@Eugene well。。。尝试
filter((Collection&RandomAccess)新建链接列表(Arrays.asList(1,2,3)),x->x>1)
。该强制转换之所以有效,是因为
List.of(1,2,3)
返回
RandomAccess
类型。由于Java在编译时没有检查对交互类型的强制转换(在类似的情况下),所以不会出现编译时错误,而是在运行时出现类强制转换异常。对,我知道并理解这一点,但同时:
System.out.println(List.of(1,2,3)instanceof RandomAccess);//是的,所以我真的不明白“…是表达式列表的静态类型。of(1,2,3)不是RandomAccess的子类型”:|@Eugene,
List.of(…)
的返回类型是
List
。而且在
List
的类型层次结构中没有编译器会知道的
RandomAccess
List->Collection->Iterable
)。如您所知,泛型边界是在编译时强制执行的(除非使用原始类型),这是基于静态类型的。而
new ArrayList()
List.of()
这两种方法都有效,因为它们返回
RandomAccess的实例(
java.util.ArrayList`和
java.util.ImmutableCollections.ListN
do实现
RandomAccess
filter(new ArrayList<>(List.of(1, 2, 3)), x -> x > 1);
filter(new ArrayList<>(List.of("a", "b", "c")), x -> x.length() > 1);