Java:过滤类似于通配符类型的项目

问题描述 投票:0回答:1

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

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

public boolean isMinimumOrThrow(Object minToCheck, Collection<Object> coll);
  1. 如果
    minToCheck
    不是
    Comparable<?>
    类型,那么我想抛出运行时异常。
  2. 否则我要过滤掉
    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);
}

有什么想法吗?

java generics casting wildcard instanceof
1个回答
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);
        
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.