1
final List<String> userIds = request.getUserIds();
final List<String> keys = userIds.stream().map(p -> { 
    return removePrefix(p); 
}).collect(Collectors.toList());

Basically, every key in the list of userIds contains a prefix "_user" which I want to remove for every key. So, I am invoking the removePrefix function on each item of the list and storing that result in another list called "keys"

Mike Lyons
  • 1,748
  • 2
  • 20
  • 33
Phoenix
  • 8,695
  • 16
  • 55
  • 88

2 Answers2

8

Yes it's fine although you could make it a little shorter and more readable with a method reference and a static import:

final List<String> keys = userIds.stream()
                                 .map(this::removePrefix)
                                 .collect(toList());
assylias
  • 321,522
  • 82
  • 660
  • 783
  • Is there any difference between `.map(p -> removePrefix(p))` and `.map(this::removePrefix)`. Yeah, the first one is longer with 2 characters, but anything else? – Nagy Vilmos Apr 14 '15 at 21:12
  • 5
    No functional difference - but I find method references more readable. It's obviously a matter of taste... – assylias Apr 14 '15 at 21:14
  • 2
    @NagyVilmos That can easily be verified... And here is more on the subject: http://stackoverflow.com/questions/24487805/lambda-expression-vs-method-reference – assylias Apr 14 '15 at 21:17
  • 2
    @Nagy Vilmos: no, they are slightly different. A method reference does not need a synthetic method to hold the lambda’s code but refers to the target method directly. Well, in most cases; sometimes it requires a helper method which is exactly like the lambda expression, e.g. for varargs methods or array constructors. – Holger Apr 15 '15 at 08:06
4

The answer of @assylias is nice, but if you are not worried about modifying the list in place (and that you are allowed to modify it via its ListIterator#set method), a good alternative could be to use replaceAll:

final List<String> userIds = request.getUserIds();
userIds.replaceAll(this::removePrefix);

replaceAll works here because your function is a function from T to T (where T is String in your case), so basically a UnaryOperator, which is a Function<T,T>.

If the mapping you wanted to apply would have been from a type T to U, then getting the list's stream and doing the mapping via the Stream#map method (like you did) is the standard idiom.

Alexis C.
  • 91,686
  • 21
  • 171
  • 177