3


I'm kind of new to generics in Java and I've faced such a problem: Let's say you have your own List implementation and you want to provide a mechanism to simultaneously convert all elements using some kind of mapping (functional interface) and collect them into a new list.

While the idea and use of functional interface (IMapper in my case) is straightforwad I can't quite think of what signature a function performing mapping should have?

Here's a little use case example and what I thought of as well. It does not work unfortunately and I guess the main problem is: How the second V param type should be passed in such case?

public interface IMapper<T,V> { V map(T v); }

public class MyList<T> extends ArrayList<T> {
  public MyList<V> map(IMapper <T,V> mapper) {
    MyList<V> list = new MyList<>();
    for(T v : this) {
      list.add(mapper.map(v));
    }
    return list;
  }
}
// in main
MyList<Integer> list1 = new MyList<>(); 
// fill etc..
IMapper<Integer,String> m = (i) -> { return i.toString(); };
// "Change" list
MyList<String> list2 = list1.map(m);

PS: I think that such thing is most probably already implemented in Java (stream() and what follows I guess?) however it suppose to be exercise for me. Any tip would be much appreciated :)

2 Answers 2

2

You can add the map result type to you function definition as following:

class MyList<T> extends ArrayList<T> {

public <V> MyList<V> map(IMapper<T, V> mapper) {
    MyList<V> list = new MyList<>();
    for (T v : this) {
        list.add(mapper.map(v));
    }
    return list;
}

}

Example:

MyList<Integer> number = new MyList<>();

number.add(1);
number.add(2);
number.add(3);

number.map(v -> "#" + v).forEach(System.out::println);

And you can have the same result using Java8 streams as following:

List<Integer> numberStream = new ArrayList<>();
numberStream.add(1);
numberStream.add(2);
numberStream.add(3);
numberStream.stream().map(v -> "#" + v).forEach(System.out::println);
Sign up to request clarification or add additional context in comments.

Comments

2

You can define the generic parameter as a type parameter on your map method. Like this:

public <V> MyList<V> map(IMapper <T,V> mapper) {
    ...
}

Type parameters can be defined in two ways, either on a class or on a method. If it's defined on a class, it can be used throughout the class. If it's defined on a method, it can only be used in that method.

In your case, the T parameter is defined on the class, while the V parameter can be defined on the method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.