Python-like list comprehension in Java Python-like list comprehension in Java python python

Python-like list comprehension in Java


In Java 8 you can use method references:

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

Or, if you want to create a new list instance:

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


Basically, you create a Function interface:

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

and then pass in an anonymous subclass to your method.

Your method could either apply the function to each element in-place:

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();    }});

or create a new List (basically creating a mapping from the input list to the output 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();    }});

Which one is preferable depends on your use case. If your list is extremely large, the in-place solution may be the only viable one; if you wish to apply many different functions to the same original list to make many derivative lists, you will want the map version.


The Google Collections library has lots of classes for working with collections and iterators at a much higher level than plain Java supports, and in a functional manner (filter, map, fold, etc.). It defines Function and Predicate interfaces and methods that use them to process collections so that you don't have to. It also has convenience functions that make dealing with Java generics less arduous.

I also use Hamcrest** for filtering collections.

The two libraries are easy to combine with adapter classes.


** Declaration of interest: I co-wrote Hamcrest