java - 强制 Stream::filter 方法在传递 Predicate 而不是 Predicate时使编译时间失败
问题描述
我正在玩与流 api 一起使用的预定义身份过滤器。不幸的是,我无法正确返回符合流 api 文档的通用谓词。
根据反编译器,这里是Stream::filter
定义:
public interface Stream<T> extends BaseStream<T, Stream<T>> {
Stream<T> filter(Predicate<? super T> var1);
我面临着任何支持 Streams (8~15) 的 Java 版本的问题。这个问题与我的实现无关。这段代码实际上足以重现它:
Collection<String> result = Stream.of("A", "B", "C")
.filter(new Object()::equals)
.filter(Integer.valueOf(-1)::equals)
.collect(Collectors.toSet());
在这里,应用了两个谓词,它们都不<? super String>
符合...
根据这个答案,这种行为似乎很奇怪......
我应该如何防止我的库的用户ServerState
通过随机对象相等检查等进行过滤...?
理想情况下,我希望始终返回正确的 Predicate<? super T> 不幸的是,没有任何编译时错误支持...
在这种情况下,使用 linter 不是解决方案。
尽管我知道下界通配符是如何工作的,但我一直缺少的是 aPredicate<? super Integer>
可以成功转换为Predicate<? super String>
.
在哪里:
Predicate<? super String> stringPredicate = (Predicate<? super String>)Filters.is_tClass(Integer.class, 4);
Predicate<? super Server> serverPredicate = (Predicate<? super Server>)Filters.is_comparable(5);
Collection<Integer> result = Stream.of(1, 2, 3)
.filter((Predicate<? super Integer>)stringPredicate)
.filter((Predicate<? super Integer>)serverPredicate)
.filter(Filters.is(new Object()))
.collect(Collectors.toSet());
导致[]
空结果集。
这是我到目前为止所拥有的,但对其中任何一个都不满意:
import java.util.Collection;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Collection<Integer> result = Stream.of(1, 2, 3)
//.filter(Filters.is_tClass(Integer.class, 4)) // enforce user to provide target class
//.filter(Filters.is_comparable(5)) // use only Comparable
.filter(Filters.is(new Server())) // fail runtime with custom exception
.collect(Collectors.toSet());
System.out.println(result);
}
private static class Server {
}
private static class Filters {
private static <T> Predicate<? super T> is(T other) {
return t -> {
// simple class equality check - error prone!
Class<?> tClass = t.getClass();
Class<?> otherClass = other.getClass();
if (!tClass.equals(otherClass)) {
throw new RuntimeException(
String.format("Check equality for [%s ? %s] seems odd. Can not continue...", tClass, otherClass));
}
return t.equals(other);
};
}
static <T> Predicate<? super T> is_tClass(Class<T> tClass, T other) {
return is(other);
}
static <T extends Comparable<T>> Predicate<? super T> is_comparable(T other) {
return is(other);
}
}
}
is_*
在此处发布示例之前不存在具有该类型名称的方法,因此将被删除...
编辑
尽管我知道下界通配符是如何工作的,但我一直缺少的是 aPredicate<? super Integer>
可以成功转换为Predicate<? super String>
.
在哪里:
Predicate<? super String> stringPredicate = (Predicate<? super String>)Filters.is_tClass(Integer.class, 4);
Predicate<? super Server> serverPredicate = (Predicate<? super Server>)Filters.is_comparable(5);
Collection<Integer> result = Stream.of(1, 2, 3)
.filter((Predicate<? super Integer>)stringPredicate)
.filter((Predicate<? super Integer>)serverPredicate)
.filter(Filters.is(new Object()))
.collect(Collectors.toSet());
导致[]
空结果集。
解决方案
在这里,应用了两个谓词,它们都不是 <? 超级字符串>兼容
这不是真的:这 2 个谓词确实消耗了一个Object
,它是 的父级String
。
<? super String>
不得与<? extends String>
.
推荐阅读
- java - 无效的 URI:content://***/my_images/JPEG_20210524_115135_2243630097715646442.jpg
- selenium - 从值或文本获取 XPath
- javascript - Chart.js 不显示/跳过标签
- php - 使用 lumen/php 从 Amazon S3 下载文件
- r - 是否可以在 RStudio 中检索控制台输出历史记录?
- adminlte - 如何记住 AdminLTE3 侧边栏的切换状态?
- bash - 如何将字符串列表与另一个文件匹配并打印前一行以进行多个匹配?
- angular - Angular:异步管道和绘图 svg
- memory-management - Linux内核中的“FOLL_FORCE”是什么意思?
- php - Laravel 身份验证“记住我”令牌