提问者:小点点

Java:筛选与通配符类型类似的项


我正在为DSL编写解释器,遇到了一个问题,我想比较两个未知类型的值。我试图将问题简化为以下内容。

我想使用以下规范定义一个具有两个参数的函数。

public boolean isMinimumOrThrow(Object minToCheck, Collection<Object> coll);
  1. 如果minToCheck不是类型可比较

我在定义过滤器时遇到了麻烦,即,

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);
}

我不确定是否可以实现

为了解决这个问题,我尝试稍微放松可比的限制,并定义了我自己的接口My可比

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);
}

有什么想法吗?


共1个答案

匿名用户

我对您的代码做了一些小的更改,我相信我得到了您想要的功能。

首先,我将函数定义为泛型:

<T> boolean isMinimumOrThrow(T minToCheck, Collection<T>)

我简化了你的过滤器,并在项目上添加了一个演员:

coll.stream().allMatch(item -> comparableMin.compareTo( (T) item) <= 0);

这是使用标准可比。我认为你的主要问题是缺少“项目”上的演员阵容。

一个带有整数的完整工作示例:

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);
        
    }
}