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.