如何在同一方法中处理多种列表?

时间:2015-08-06 02:11:24

标签: java

我目前有这些签名的方法:

public static List<Integer> keep(List<Integer> input, Predicate<Integer> p)

public static List<String> keep(List<String> input, Predicate<String> p)

public static List<List<Integer>> keep(List<List<Integer>> input, Predicate<List<Integer>> p)

所有人都做同样的事情。如何在一种方法中处理这三种列表中的任何一种?我已经尝试使用通配符(?)运算符,但是当我这样做时,我收到一条错误,指出无法将CAP#1对象添加到列表中。

以下是其中一种方法的示例:

public static List<?> keep(List<?> input, Predicate<?> p) {
    List<?> keepList = new ArrayList<>();

    input.stream().filter((i) -> (p.test(i))).forEach((i) -> {
        keepList.add(i);
    });

    return keepList;
}

在此方法中,keepList.add(i)生成一个错误:

  

找不到合适的添加方法(CAP#1)

     

方法Collection.add(CAP#2)不适用         (参数不匹配;对象无法转换为CAP#2)

     

方法List.add(CAP#2)不适用         (参数不匹配;对象无法转换为CAP#2)

     

其中CAP#1,CAP#2是新的类型变量:       CAP#1扩展了Object的捕获?

     

CAP#2扩展了Object的捕获?

2 个答案:

答案 0 :(得分:0)

使用通用方法。

public static <T> List<T> method(List<T> list) {
    ...
}

如果需要,您可以像对待课程一样限制T;例如T extends Number或其他什么。

答案 1 :(得分:0)

是的,完全基于类型签名,您可以使用泛型。为方法定义一个类型参数,并将其用作每个列表/谓词的类型。

public static <X> List<X> keep(List<X> input, Predicate<X> p)

考虑java.util.function.Predicate的工作方式以及方法keep的名称,这可能足以使您的代码通用并将3个函数减少为一个函数。