Zenoo
Zenoo

Reputation: 12880

Passing a lambda function as a parameter

I'm trying to create an equivalent to Javascript's Array#map in Java.

I have been able to do it with

ArrayList<String> data = myList.stream().map(e -> {
    return "test "+e;
}).collect(Collectors.toCollection(ArrayList::new));

Here, myList is the initial ArrayList and data is the resulting ArrayList.

However, I find it very tedious to do that every time.

So I tried to create a generic function that would make my life easier :

public static ArrayList<?> map(ArrayList<?> list, Function<? super Object,?> callback){
    return list.stream().map(callback).collect(Collectors.toCollection(ArrayList::new));
}

And then calling it with:

ArrayList<String> data = DEF.map(myList,e -> {
    return "test "+e;
});

But I get the error

[Java] The method map(ArrayList, Function) in the type DEF is not applicable for the arguments (List, ( e) -> {})

How can I edit my generic function to accept the lambda I'm using?

Upvotes: 2

Views: 690

Answers (1)

Eran
Eran

Reputation: 394026

You should define your method with two generic type parameters - the element type of the source list, and the element type of the target list :

public static <S,T> ArrayList<T> map(ArrayList<S> list, Function<S,T> callback)
{
    return list.stream().map(callback).collect(Collectors.toCollection(ArrayList::new));
}

It would also be better to use the List interface instead of ArrayList:

public static <S,T> List<T> map(List<S> list, Function<S,T> callback)
{
    return list.stream().map(callback).collect(Collectors.toList());
}

Example of usage:

List<Integer> myList = Arrays.asList (1,2,3,4);
List<String> datai = map(myList ,e -> "test " + e);

Output:

[test 1, test 2, test 3, test 4]

Upvotes: 10

Related Questions