0

I've already looked here, that works for an argument less method list containing Runnables. I need to have Consumer in my case. This is what I have so far:

import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.function.Consumer;

public class experiment {

 private static List<Consumer<String>> activities;

 public experiment (){
 activities = ImmutableList.of(
     (userId) -> this::bar,        // throws error
     (userId) -> this::foo);
 }

 public void bar(String x) {
   System.out.println(x);
 }

 public void foo(String x) {
   System.out.println(x);
 }

 public static void main(String []args) {

  for (int i=0; i<2; i++) {
    activities.get(i).accept("activity #" + i);
  }
 }
}

The error I see is void is not a functional interface.

I don't understand why I'm getting that, both bar and foo implement the accept method of the Consumer interface. Is there something I'm overlooking here?

Community
  • 1
  • 1
Siddhartha
  • 4,296
  • 6
  • 44
  • 65
  • Java doesn't have functions pointers, its lambda or method references – Sleiman Jneidi Nov 20 '15 at 23:20
  • 1
    Unconditionally initializing a static field in the constructor is very bad logic. Either initialize in a static initializer block, or change field to non-static. – Andreas Nov 20 '15 at 23:29

2 Answers2

6

I believe you want to write ImmutableList.of(this::bar, this::foo) instead of ImmutableList.of((userId) -> this::bar, (userId) -> this::foo).

If you do want to use lambdas instead of method references, you should instead write ImmutableList.of((userId) -> this.bar(userId), (userId) -> this.foo(userId)).

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • Nice and concise answer. Of course, once these changes are applied and the code compiles, the next problem is NPE caused by `activities` being null. – Andreas Nov 20 '15 at 23:27
0

Your lambda's are wrong. You either supply a method reference, or you supply a lambda expression. You're trying an incorrect combo.

Also, your two methods foo() and bar() should be static, and your instance variable should not be. To show how instance methods could be called, I've added baz() and qux().

Here's showing full example:

public class Experiment {

    private List<Consumer<String>> activities;

    public Experiment() {
        this.activities = ImmutableList.of(
            (userId) -> Experiment.bar(userId),
            Experiment::foo,
            (userId) -> this.baz(userId),
            this::qux
        );
    }

    public static void bar(String x) {
        System.out.println(x);
    }

    public static void foo(String x) {
        System.out.println(x);
    }

    public void baz(String x) {
        System.out.println(this.hashCode() + ": " + x);
    }

    public void qux(String x) {
        System.out.println(this.hashCode() + ": " + x);
    }

    public static void main(String[] args) {
        Experiment ex = new Experiment();
        for (int i = 0; i < ex.activities.size(); i++) {
            ex.activities.get(i).accept("activity #" + i);
        }
    }
}
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • The methods don't _have_ to be static, but it'd probably make sense for them to be. – Louis Wasserman Nov 20 '15 at 23:22
  • @LouisWasserman and Andreas, Why do you 2 recommend them to be static? In my case, the functions are instance specific and reference a bunch of instance variables. – Siddhartha Nov 20 '15 at 23:30
  • Thanks for the answer btw. – Siddhartha Nov 20 '15 at 23:30
  • Sure, then they can be instance methods. activities should be an instance variable too, though. – Louis Wasserman Nov 20 '15 at 23:35
  • @Siddhartha We can only recommend things based on what you show. Static field initialized by constructor is bad and needed to be addressed. Using an instance method reference to a method that doesn't have any instance logic needed a comment about better usage. The lack of invoking the constructor was really bad, and was really unrelated to question, but you included `main()` method for a reason, so needed to be addressed. – Andreas Nov 21 '15 at 00:50