我正在为 DSL 编写一个解释器,我遇到了一个问题,我想比较两个未知类型的值。我试图将问题简化为以下内容。
我想用以下规范定义一个带有两个参数的函数。
public boolean isMinimumOrThrow(Object minToCheck, Collection<Object> coll);
minToCheck
不是Comparable<?>
类型,那么我想抛出运行时异常。coll
中所有可以和minToCheck
比较的对象,然后返回minToCheck
是否小于等于coll
中的每一个可比较对象。我在定义过滤器时遇到了麻烦,即,
public boolean isMinimumOrThrow(Object minToCheck, Collection<Object> coll) {
if (!(minToCheck instanceof Comparable<?>)) {
throw new RuntimeException();
}
Comparable<?> comparableMin = (Comparable<?>)minToCheck;
return coll.stream().filter(...).allMatch(item -> comparableMin.compareTo(item) <= 0);
}
我不确定是否可以实施
...
.
为了解决这个问题,我试着放宽了
Comparable
的限制,并定义了我自己的接口MyComparable<T>
public interface MyComparable<T> extends Comparable<T> {
public Collection<T> filterComparable(Collection<?> values);
}
但即便如此,我仍然遇到类型错误
The method compareTo(capture#13-of ?) in the type Comparable<capture#13-of ?> is not applicable for the arguments (capture#12-of ?)
使用以下代码
public boolean isMinimumOrThrow(Object minToCheck, Collection<Object> coll) {
if (!(minToCheck instanceof MyComparable<?>)) {
throw new RuntimeException();
}
MyComparable<?> comparableMin = (MyComparable<?>)minToCheck;
return comparableMin.filterComparable(coll).stream().allMatch(item -> comparableMin.compareTo(item) <= 0);
}
有什么想法吗?
我对你的代码做了一些小的改动,我相信我已经按照你想要的方式工作了。
首先我将函数定义为泛型:
<T> boolean isMinimumOrThrow(T minToCheck, Collection<T>)
我稍微简化了你的过滤器,并在项目上为 T 添加了一个演员表:
coll.stream().allMatch(item -> comparableMin.compareTo( (T) item) <= 0);
这是使用标准的 Comparable。我认为你的主要问题是缺少“项目”的演员阵容。
一个完整的整数示例:
import java.util.Collection;
import java.util.List;
import java.util.Arrays;
import java.lang.Comparable;
public class Program
{
static <T> boolean isMinimumOrThrow(T minToCheck, Collection<T> coll) {
if (!(minToCheck instanceof Comparable<?>)) {
throw new RuntimeException();
}
Comparable<T> comparableMin = (Comparable<T>) minToCheck;
return coll.stream().allMatch(
item -> comparableMin.compareTo( (T) item) <= 0
);
}
public static void main(String[] args) {
boolean isMinimum = false;
Collection<Integer> list = Arrays.asList(1,2,3,4,5);
isMinimum = isMinimumOrThrow(0, list);
System.out.println("Is minimum: " + isMinimum);
}
}