如何让方法适配实现指定接口的任意类?泛型可行吗?
如何让方法适配所有实现
String getValue()接口的类(泛型解决方案) 问题根源
你之前的泛型方法参数用了List<GetValueToStringObject>,但Java泛型是不变的——List<ColValueObject>并不是List<GetValueToStringObject>的子类,哪怕ColValueObject实现了该接口。这是因为如果允许这样赋值,你可以往List<GetValueToStringObject>中添加其他实现类的对象,会破坏集合的类型安全,所以编译器直接报错。
正确的泛型实现方案
我们可以通过有界通配符或泛型类型参数来解决这个问题,同时还能优化方法的性能(原来的嵌套循环时间复杂度是O(n*m),用Set存储查询可以降到O(n+m))。
方案1:使用有界通配符(兼容不同实现类的List)
import java.util.List; import java.util.Set; import java.util.stream.Collectors; private static void findUniqueEntriesInListUsingGenerics( List<? extends GetValueToStringObject> list1, List<? extends GetValueToStringObject> list2, List<? super GetValueToStringObject> result) { // 提前把list2的所有value存入Set,提升查询效率 Set<String> list2Values = list2.stream() .map(GetValueToStringObject::getValue) .collect(Collectors.toSet()); for (GetValueToStringObject l1 : list1) { if (!list2Values.contains(l1.getValue())) { result.add(l1); } } }
? extends GetValueToStringObject:表示方法接受任何实现了GetValueToStringObject接口的类的List,不管是ColValueObject还是其他实现类。? super GetValueToStringObject:遵循PECS原则(生产者用Extends,消费者用Super),result作为“消费者”(要添加元素),可以接受接口本身或其父类的List,保证能安全添加list1中的元素。
方案2:使用泛型类型参数(保证result类型与list1一致)
如果需要result的类型和list1完全匹配(比如List<ColValueObject>),可以用泛型类型参数:
import java.util.List; import java.util.Set; import java.util.stream.Collectors; private static <T extends GetValueToStringObject> void findUniqueEntriesInListUsingGenerics( List<T> list1, List<? extends GetValueToStringObject> list2, List<T> result) { Set<String> list2Values = list2.stream() .map(GetValueToStringObject::getValue) .collect(Collectors.toSet()); for (T l1 : list1) { if (!list2Values.contains(l1.getValue())) { result.add(l1); } } }
这个版本中,T绑定了list1和result的类型,确保添加到result的元素类型完全匹配,避免后续类型转换的麻烦。
调用方式
现在你可以直接像之前那样调用方法,编译器不会再报错:
findUniqueEntriesInListUsingGenerics(list1, list2, result);
内容的提问来源于stack exchange,提问作者tm1701
相关产品推荐
相关产品推荐

