6

I am trying to make use of lambdas in Java but can't understand how it works at all. I created @FunctionalInterface like this:

@FunctionalInterface
public interface MyFunctionalInterface {
    String getString(String s);
}

now in my code I use the lambda as here:

MyFunctionalInterface function = (f) -> {
    Date d = new Date();
    return d.toString() + " " + person.name + " used fnc str";
};

Next, I want to make use of my function passing it into the constructor of another class and use it like this:

public SampleClass(MyFunctionalInterface function) {
    String tmp = "The person info: %s";
    this.result = String.format(tmp, function.getString(String.valueOf(function)));
}

Why I need to use it the valueOf() here? I thought that thanks for this I could use just function.getString()?

Output: Tue Sep 19 11:04:48 CEST 2017 John used fnc str

shurrok
  • 795
  • 2
  • 13
  • 43
  • Your function takes a `String` as a parameter. Reading your string format, you should pass the person info as a `String` to it. Right now, you are passing the string representation of the function itself, to the function. – marstran Sep 19 '17 at 09:00
  • It is not really clear what you are trying to achieve. I would have expected that lambda definition in the place where you use function. Or that you use a method reference. I think the code you have right now will turn the OBJECT that function also represents and create a string representation of that, which is then passed as input to the function itself. Simply doesn't make sense. – GhostCat Sep 19 '17 at 09:01
  • What is the output of this code? – jrook Sep 19 '17 at 09:01
  • @jrook added output – shurrok Sep 19 '17 at 09:06

1 Answers1

5

Your getString method requires a String argument, so you can't call it without any argument.

That said, your lambda expression ignores that String argument and instead takes data from some person variable (which you didn't show where you declare it).

Perhaps your functional interface should take a Person argument instead:

@FunctionalInterface
public interface MyFunctionalInterface {
    String getString(Person p);
}

MyFunctionalInterface function = p -> {
    Date d = new Date();
    return d.toString() + " " + p.name + " used fnc str";
};

public SampleClass(MyFunctionalInterface function, Person person) {
    String tmp = "The person info: %s";
    this.result = String.format(tmp, function.getString(person));
}

Alternately, you can remove the argument from your functional interface's method:

@FunctionalInterface
public interface MyFunctionalInterface {
    String getString();
}

MyFunctionalInterface function = () -> {
    Date d = new Date();
    return d.toString() + " " + person.name + " used fnc str";
};

public SampleClass(MyFunctionalInterface function) {
    String tmp = "The person info: %s";
    this.result = String.format(tmp, function.getString());
}
Eran
  • 387,369
  • 54
  • 702
  • 768
  • Hmm, I cannot pass there a specific object because I would like to format many of them with this `Inerface`, not just a `person` (e.g `car`, `animal` and so on) – shurrok Sep 19 '17 at 09:07
  • @soommy12 In that case, perhaps you can make the functional interface generic - `interface MyFunctionalInterface`. Of course, if you intend to use specific properties such as p.name, you will have to place some type bound on T (`` where `SomeType` is a class that has a `name` property). Otherwise, you can remove the argument from the `getString()` method (and from your lambda expression), and keep everything else as is. – Eran Sep 19 '17 at 09:11
  • Ok, but another question is can I make my Interface to takes nothing and return `String` then? I mean, I would like to make some kind of "abstract method" in here. I want to do things with the `String` and return it. Can I achieve this by lamdas? – shurrok Sep 19 '17 at 09:23
  • 1
    @soommy12 Of course you can. For example - `MyFunctionalInterface function = () -> { Date d = new Date(); return d.toString() + " " + person.name + " used fnc str"; };` – Eran Sep 19 '17 at 09:24
  • This is exactly what I wanted! – shurrok Sep 19 '17 at 09:34
  • 1
    @soommy12 I added that to the answer. – Eran Sep 19 '17 at 09:36
  • 1
    @soommy12 Note that many simple functional interfaces are already provided for you in the `java.util.function` package. The standard interface that consumes nothing but returns a value is `Supplier`. You need not write your own. – Mike Strobel Sep 19 '17 at 10:24