Java中类似Python的列表理解

由于Java不允许将方法作为参数传递,那么您使用什么技巧来实现Python,例如Java中的列表理解?

我有一个字符串列表(ArrayList)。我需要使用函数转换每个元素,以便获得另一个列表。我有几个函数,它们将一个字符串作为输入,并返回另一个字符串作为输出。我如何制作一个泛型方法,可以将列表和函数作为参数,以便我可以获得一个列表,并处理每个元素。从字面意义上讲,这是不可能的,但是我应该使用什么技巧?

另一种选择是为每个较小的字符串处理函数编写一个新函数,该函数只是循环遍历整个列表,这有点不那么酷。


答案 1

在 Java 8 中,您可以使用方法引用:

List<String> list = ...;
list.replaceAll(String::toUpperCase);

或者,如果要创建新的列表实例:

List<String> upper = list.stream().map(String::toUpperCase).collect(Collectors.toList());

答案 2

基本上,您创建一个函数接口:

public interface Func<In, Out> {
    public Out apply(In in);
}

,然后将匿名子类传递给您的方法。

您的方法可以将函数就地应用于每个元素:

public static <T> void applyToListInPlace(List<T> list, Func<T, T> f) {
    ListIterator<T> itr = list.listIterator();
    while (itr.hasNext()) {
        T output = f.apply(itr.next());
        itr.set(output);
    }
}
// ...
List<String> myList = ...;
applyToListInPlace(myList, new Func<String, String>() {
    public String apply(String in) {
        return in.toLowerCase();
    }
});

或者创建一个新的(基本上创建从输入列表到输出列表的映射):List

public static <In, Out> List<Out> map(List<In> in, Func<In, Out> f) {
    List<Out> out = new ArrayList<Out>(in.size());
    for (In inObj : in) {
        out.add(f.apply(inObj));
    }
    return out;
}
// ...
List<String> myList = ...;
List<String> lowerCased = map(myList, new Func<String, String>() {
    public String apply(String in) {
        return in.toLowerCase();
    }
});

哪一个更可取取决于您的用例。如果您的列表非常大,则就地解决方案可能是唯一可行的解决方案;如果您希望将许多不同的函数应用于同一原始列表以制作许多衍生列表,则需要该版本。map