使用通用 java 接口获取意外参数类型并实现

Posted

技术标签:

【中文标题】使用通用 java 接口获取意外参数类型并实现【英文标题】:Getting unexpected argument types with and implementing generic java interface 【发布时间】:2021-12-16 01:29:35 【问题描述】:

我创建了一个名为 Predicate 的通用接口,并创建了许多实现该接口的类。

以下是我的谓词接口:

package predicates;

interface Predicate<T> 
    public boolean startsWith(T t);
    public boolean accepts(T t);
    public boolean greaterThan(T t);
    public boolean subsetOf(T t);
    public boolean negation(T t);
    public boolean acceptsAllOf(T t);
    public boolean acceptsSomeOf(T t);
    public boolean acceptsMostOf(T t);
    public boolean mostAcceptsMostOf(T t);
    public boolean and(T t);
    public boolean or(T t);

以下是我对名为 SubsetOf 的谓词接口的实现(注意它现在什么都不做):

package predicates;

import java.util.Collection;

public class SubsetOf<T> implements Predicate<T> 

    public SubsetOf(Collection<T> t) 
        
    

    @Override
    public boolean startsWith(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean accepts(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean greaterThan(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean subsetOf(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean negation(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean acceptsAllOf(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean acceptsSomeOf(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean acceptsMostOf(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean mostAcceptsMostOf(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean and(T t) 
        // TODO Auto-generated method stub
        return false;
    

    @Override
    public boolean or(T t) 
        // TODO Auto-generated method stub
        return false;
    
    
    


这两个函数是我创建对象并对其运行测试的地方:

public static void subsetOf() 
        SubsetOf<String> predicate = new SubsetOf<String>( Arrays.asList("mad", "men") );
        List<Collection<? extends String>> tests = 
                Arrays.asList( 
                        Arrays.asList("mad", "men"),
                        Arrays.asList("men", "mad"),
                        Arrays.asList("men", "women", "rams", "mad"),
                        Arrays.asList("mad", "cowboy"),
                        Arrays.asList() );
        List<Boolean> oracle = Arrays.asList( true, true, false, false, true );
        
        test( "SubsetOf<String>(mad, men)", predicate, tests, oracle );             
    
public static <T> void test( String msg, Predicate<T> predicate, List<T> tests, List<Boolean> expected ) 
        List<Boolean> actual = results( predicate, tests );
        
        System.out.print( pad(msg) );
        if( !actual.equals(expected) ) 
            System.out.println( " FAILURE" );
            for(int i=0; i<actual.size(); i++ ) 
                System.out.println( "\t\t" + tests.get(i) + "=>" + actual.get(i) + ":" + expected.get(i));
            
         else 
            System.out.println( " SUCCESS" );
        
    

这一行是问题区域:

test( "SubsetOf<String>(mad, men)", predicate, tests, oracle );     

我遇到的问题是以上两段代码不能以任何方式更改。我觉得我对所有内容的编码都应与函数参数匹配,但是我收到以下错误:

Tester 类型中的方法 test(String, Predicate, List, List) 不适用于参数 (String, SubsetOf, List>, List)

我觉得好像我已经正确陈述和实例化了应该将 SubsetOf 识别为谓词的位置,并且 List> 应该被解释为 List。我已经尝试了几个小时的不同配置,但没有取得任何进展。任何想法将不胜感激。

【问题讨论】:

那是因为您现在希望函数test(String, Predicate&lt;T&gt;, List&lt;T&gt;, List) 中的第三个参数接受T 的集合列表,而不是声明的T 列表。您需要在test 方法的签名中指明正确的参数类型。像List&lt;Collection&lt;? extends String&gt;&gt; 这样的构造也没有任何意义,因为 String 是最终类,不能扩展;它应该只是List&lt;Collection&lt;String&gt;&gt; 另外,没有必要让SubsetOf&lt;T&gt; 成为Predicate&lt;T&gt; 的实现,然后在内部实现所有方法,如greaterThanstartsWith,因为它们看起来不正确。相反,您可以直接在 Predicate 接口中创建一个默认方法,该方法接受 T 的集合,但即使这样,Predicate 定义也看起来像一个不相关(与给定类型 T 方法)的混合,例如例如,greaterThan 适用于可比较的类型,subsetOf 适用于 2 个集合 【参考方案1】:

也许你可以试试这个:

List<Collection<String>> tests = 
                Arrays.asList( 
                        Arrays.asList("mad", "men"),
                        Arrays.asList("men", "mad"),
                        Arrays.asList("men", "women", "rams", "mad"),
                        Arrays.asList("mad", "cowboy"),
                        Arrays.asList() );
public static <T> void test(String msg, Predicate<T> predicate, List<Collection<T>> tests, List<Boolean> expected )

【讨论】:

以上是关于使用通用 java 接口获取意外参数类型并实现的主要内容,如果未能解决你的问题,请参考以下文章

如何在具有通用参数类型的接口中实现函数?

在 Room 中创建通用 DAO 接口时,“参数的类型必须是带有 @Entity 注释的类”

泛型反射

Effective Java2读书笔记-对于所有对象都通用的方法

java 泛型

打字稿:使用特定的扩展接口来满足通用的“扩展”类型参数?