6

Can someone explain me, how come both of the lambdas can be replaced with method references here?

In RxJava, map() takes a parameter of type Func1<T, R>, whose comment states that it "Represents a function with one argument". Thus I completely understand why valueOf(Object) works here. But trim() takes no arguments at all.

So how does this work exactly?

Observable.just("")
    .map(s -> String.valueOf(s))  //lambdas
    .map(s -> s.trim())           //

    .map(String::valueOf)         //method references
    .map(String::trim)            //
    .subscribe();
Grzegorz D.
  • 1,748
  • 15
  • 18
  • 2
    The way method references work is that for instance methods like `trim`, `Type::instanceMethod` is equivalent to `(Type t) -> t.instanceMethod()`. (More generally, `Type::instanceMethod` is `(Type t, extraArgs) -> t.instanceMethod(extraArgs)`.) – Louis Wasserman Nov 10 '16 at 20:23

1 Answers1

3

I didn't play with RX in java, but please note, that String::valueOf is a static (aka unbound) function, while String::trim is a non-static (aka bound) function that have indirect this argument. So, in fact, both function takes single argument. In Java it's not that visible as it is in Python for example.

Michał Šrajer
  • 30,364
  • 7
  • 62
  • 85
  • 4
    Note that you can actually explicitly declare the `this` argument in Java; it just isn't required. `public void foo(Foo this) {}` is equivalent to `public void foo(){}`. – Pokechu22 Nov 10 '16 at 19:00
  • @Pokechu22 I like this. Wasn't aware. Since what java version? Do you know? – Michał Šrajer Nov 10 '16 at 19:38
  • I'm pretty sure it was added in Java 8. – Pokechu22 Nov 10 '16 at 20:06
  • 2
    The `Foo this` is called a "receiver parameter" and is specified in [JLS, §8.4.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.1). You can do the same thing with inner class constructors, e.g. an outer class `Foo` with inner class `Bar` whose constructor can be written as `Bar(Foo Foo.this)`. – Stefan Zobel Nov 11 '16 at 12:43