8

I'm looking for a way to map a tab separated String to an array. Currently, I'm doing it with a lambda expression:

stream.map(line -> line.split("\t"));

Is there a way to do it with a method reference? I know that stream.map(String::split("\t")) does not work, but am wondering if there is an alternative.

mossaab
  • 1,812
  • 4
  • 23
  • 44
  • You mean a reference to an existing method in the JDK? Because you can easily make a MyStringUtils::splitByTab and reference that. – Thilo Nov 14 '14 at 00:25
  • 2
    I mean in general. I.e., whenever a method has an argument. – mossaab Nov 14 '14 at 00:32
  • Ah, so you are looking for the Java equivalent of curried methods or Javascript `bind` (which can inject parameters). +1 for that. – Thilo Nov 14 '14 at 00:33
  • I guess so (I hadn't heard of curried methods before). Misha seems to propose such a solution. – mossaab Nov 14 '14 at 01:21
  • I assume you have a stream of tab-separated Strings, but what exact output type to you want? A single `String[]` with all of the individual split strings? Something else? – Bohemian Nov 14 '14 at 04:24
  • 1
    `split` is just a simple instance of a general need. Sometimes I need to do `stream.map(line -> line.indexOf("bla"));` or `stream.filter(line -> line.contains("bla"));` – mossaab Nov 14 '14 at 22:10

1 Answers1

8

You can do something like this:

static<T,U,R> Function<T,R> curry(BiFunction<? super T, ? super U, ? extends R> f, U u) {
    return t -> f.apply(t, u);
}

and then you'll be able to do:

stream.map(curry(String::split, "\t"));
Misha
  • 27,433
  • 6
  • 62
  • 78
  • 3
    You can simplify the signature by replacing `? super U` with `U` as the second parameter `U u` will accept subtypes of `U` anyway (this differs from `T` and `R` as these two are used by the return type). – Holger Nov 14 '14 at 09:34
  • 6
    This works, but this is like walking around the building to go next door; you're introducing a new abstraction just so you can use a method reference. The code is clearer and simpler using a lambda. – Brian Goetz Nov 14 '14 at 16:28
  • 1
    Regardless of what the OP was trying to do, the following declaration would be truer to what currying is: `public static Function> curry(BiFunction super T, ? super U, ? extends R> bf) {return t -> u -> bf.apply(t, u);}`. – jub0bs Nov 27 '15 at 21:48