Java 泛型返回参数化为更具体的两种类型的泛型?

标签 java generics wildcard

我目前有一个项目,我正在使用一组实现通用 Filter<T extends Entity> 的类来过滤一些实体。类,其中 T 是特定过滤器将处理的最具体的实体。一直创建新实例有点冗长,所以我还构建了一个构建器。一切都很棒,除了现在我尝试将 AndFilter 添加到构建器。

这是我的 AndFilter 的样子

public class AndFilter<T extends Entity> implements Filter<T>{
    private Filter<? super T> a;
    private Filter<? super T> b;

    public AndFilter(Filter<? super T> a, Filter<? super T> b){
        this.a = a;
        this.b = b;
    }

    @Override
    public boolean shouldInclude(T entity) {
        return a.shouldInclude(entity) && b.shouldInclude(entity);
    }
}

这是我一直在尝试使用的构建函数(我的构建器只是 Filter 界面中的默认函数)

public interface Filter<T extends Entity> {
    boolean shouldInclude(T entity);

    default AndFilter and(Filter<? extends Entity> other){
        return new AndFilter<>(this, other);
    }

    default Filter<T> not(){
        return new NotFilter<>(this);
    }
}

我需要能够参数化 and() 的返回,但我所做的所有尝试都失败了。理论上,AndFilter 应该参数化为 this 或 other 的类型,以更具体的为准,但我不知道如何才能做到这一点,而且我开始认为这根本不可能。如果不是,任何关于我可以实现类似行为的替代方法的建议(不必调用 new AndFilter<>(x, y) 来 AND 比较两个过滤器)将不胜感激。

编辑:我有各种继承自实体的类,它们都有自己的私有(private)属性。

实体 -> 动物 -> 捕食者、掠食者

实体 -> 障碍

实体 -> 植物

所以我有一个 DistanceFilter 实现过滤器(因为所有实体都有位置,因此有距离),但我也有 AggressionFilter 实现过滤器,因为只有掠夺者具有攻击属性。检查捕食者是否满足两个过滤器应该是可能的,因为捕食者具有所有必需的属性,并且它确实有效。我可以调用 new AndFilter<>(new DistanceFilter(), new AggressionFilter()) 并且它工作正常,但是当我尝试将该初始化放在函数后面时,我无法让返回类型工作

最佳答案

AndFilter 有一个参数化类型,AndFilter 应该由 T 绑定(bind)。AndFilter 应该由与其绑定(bind)类型相同的 Filter 对象组成,T 扩展了 Entity。

default AndFilter<T> and(Filter<? extends Entity> other){
    return new AndFilter<>(this, other);
}
public class AndFilter<T extends Entity> implements Filter<T>{

    private Filter<T> a;

    private Filter<T> b;

    public AndFilter(Filter<T> a, Filter<T> b){
        this.a = a;
        this.b = b;
    }
}

使用类 MyEntity 实现的示例,该类扩展了 Entity,并具有 String 类型的单个类成员 name

        MyEntity foo = new MyEntity("Foo");

        MyEntity bar = new MyEntity("Bar");

        MyEntity fooBar = new MyEntity("FooBar");

        Filter<MyEntity> fooFilter = e -> e.name.contains("Foo");

        Filter<MyEntity> barFilter = e -> e.name.contains("Bar");

        Filter<MyEntity> fooBarFilter = fooFilter.and(barFilter);

        System.out.println(String.format("Foo: %s", fooFilter.shouldInclude(foo)));
        System.out.println(String.format("Bar: %s", barFilter.shouldInclude(bar)));
        System.out.println(String.format("FooBar: %s", fooBarFilter.shouldInclude(fooBar)));

关于Java 泛型返回参数化为更具体的两种类型的泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61230221/

相关文章:

java - 使用 JPA 映射多对多关系与属性

非 GUI 应用程序中的 javax.swing.event.EventListenerList

C# System.Collections.Generic.Dictionary`2.Insert - 已添加具有相同键的项目

java - 避免返回通配符类型的方法

javascript - 使用 getElementsByTagName ('*' )/Wildcard 查找 ID 的一部分

java - spring-mvc 应用程序出现 tomcat 404 错误

java - 在 JAXB 编码中使用 BigDecimal

Objective-C 泛型 - 有没有办法使泛型与类匹配(在继承的情况下)

Java 通用比较器未检查警告

mysql - 使用通配符进行搜索的存储过程