Understanding a Python List in Java

Since Java does not allow methods to be passed as parameters, what trick do you use to implement an understanding of Python as in Java?

I have a list of (ArrayList) strings. I need to convert each item using a function to get a different list. I have several functions that take a string as input and return another string as output. How to create a general method to which you can assign a list and a function as parameters, so that I can get a list with the processed element. This is literally impossible, but what trick should I use?

Another option is to write a new function for each smaller string processing function, which simply iterates over the whole list, which is not so cool.

+49
java python methods parameters list-comprehension
May 22 '09 at 17:57
source share
6 answers

Basically, you create a functional interface:

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

and then pass an anonymous subclass to your method.

Your method can either apply a 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 an input list to an 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, an in-place solution may be the only viable; if you want to apply many different functions to the same source list, to make many lists of derivatives, you will need the map version.

+33
May 22 '09 at 18:03
source share

In Java 8, you can use method references:

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

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

 List<String> upper = list.stream().map(String::toUpperCase).collect(Collectors.toList()); 
+35
May 24 '13 at 9:52
source share

The Google Collection Library has many classes for working with collections and iterators at a much higher level than simple Java support, as well as in a functional way (filter, map, bend, etc.). It defines function and predicate interfaces and methods that use them to process collections, so you don't need to. It also has handy features that make working with Java generics less complicated.

I also use Hamcrest ** to filter collections.

Two libraries are easy to combine with adapter classes.




** Statement of Interest: I co-wrote Hamcrest

+16
May 22 '09 at 18:02
source share

Apache Commons CollectionsUtil.transform (Collection, Transformer) is another option.

+5
May 22 '09 at 18:54
source share

I am creating this project for writing lists in Java, now this is a proof of concept at https://github.com/farolfo/list-comprehension-in-java

Examples

 // { x | x E {1,2,3,4} ^ x is even } // gives {2,4} Predicate<Integer> even = x -> x % 2 == 0; List<Integer> evens = new ListComprehension<Integer>() .suchThat(x -> { x.belongsTo(Arrays.asList(1, 2, 3, 4)); x.is(even); }); // evens = {2,4}; 

And if we want to somehow transform the output expression, for example

 // { x * 2 | x E {1,2,3,4} ^ x is even } // gives {4,8} List<Integer> duplicated = new ListComprehension<Integer>() .giveMeAll((Integer x) -> x * 2) .suchThat(x -> { x.belongsTo(Arrays.asList(1, 2, 3, 4)); x.is(even); }); // duplicated = {4,8} 
+1
Jun 18 '15 at 18:58
source share

You can use lambdas for a function, for example:

 class Comprehension<T> { /** *in: List int *func: Function to do to each entry */ public List<T> comp(List<T> in, Function<T, T> func) { List<T> out = new ArrayList<T>(); for(T o: in) { out.add(func.apply(o)); } return out; } } 

using:

 List<String> stuff = new ArrayList<String>(); stuff.add("a"); stuff.add("b"); stuff.add("c"); stuff.add("d"); stuff.add("cheese"); List<String> newStuff = new Comprehension<String>().comp(stuff, (a) -> { //The <String> tells the comprehension to return an ArrayList<String> a.equals("a")? "1": (a.equals("b")? "2": (a.equals("c")? "3": (a.equals("d")? "4": a ))) }); 

will return:

 ["1", "2", "3", "4", "cheese"] 
0
Aug 23 '16 at 12:29
source share



All Articles