Java中类似Python的列表理解

eup*_*a83 52 python java parameters methods list-comprehension

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

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

另一种选择是为每个较小的String处理函数编写一个新函数,它只是循环遍历整个列表,这有点不太酷.

yur*_*rez 50

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

List<String> list = ...;
list.replaceAll(String::toUpperCase);
Run Code Online (Sandbox Code Playgroud)

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

List<String> upper = list.stream().map(String::toUpperCase).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • 问题是7岁,Java 8当时不存在.这应该是现在接受的答案;) (12认同)

Mic*_*ers 35

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

public interface Func<In, Out> {
    public Out apply(In in);
}
Run Code Online (Sandbox Code Playgroud)

然后将一个匿名子类传递给您的方法.

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

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();
    }
});
Run Code Online (Sandbox Code Playgroud)

或创建一个新的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();
    }
});
Run Code Online (Sandbox Code Playgroud)

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


Nat*_*Nat 17

谷歌集合库拥有大量的类以高得多的水平集合和迭代工作比普通的Java支持,并以功能性方式(过滤器,地图,折叠,等等).它定义了Function和Predicate接口以及使用它们处理集合的方法,以便您不必这样做.它还具有便利功能,使得处理Java泛型不那么艰巨.

我也使用Hamcrest**来过滤集合.

这两个库很容易与适配器类结合使用.


**利益声明:我与Hamcrest共同撰写

  • 这是"匹配者"的字谜. (15认同)
  • 出于好奇,为什么叫Hamcrest?我仍然无法弄清楚它听起来是否美味. (13认同)

小智 5

Apache Commons CollectionsUtil.transform(Collection,Transformer) 是另一种选择.