Rohit RC
Rohit RC

Reputation: 469

Java Consumer Interface

someone can help me understand below code from Java 8 Functional Interface As per my understanding accept() takes as input and process it but does not return any value then in case of andThen() how it works

accept() method takes as input the type T and returns no value.

default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
}

Upvotes: 5

Views: 4206

Answers (3)

mate00
mate00

Reputation: 2955

I think I understand your concern. You wonder why could you call andThen() after accept() if accept() returns void.

The thing is, that you first define a Consumer object, and on that instance you call andThen() method. For example:

Consumer<String> consumer = s -> System.out.println(s);
consumer.andThen(s -> System.out.println(s.toUpperCase()));        

Upvotes: 0

Naman
Naman

Reputation: 31878

In order to understand what is getting returned from that API, you can try visualizing the implementation as :

default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return new Consumer<T>() { // return the complete Consumer implementation
        @Override
        public void accept(T t) {
            Consumer.this.accept(t); // accept current consumer
            after.accept(t); // and then accept the 'after' one.
        }
    };
}

and now relate that

(T t) -> { accept(t); after.accept(t); } 

is a Consumer returned which ensures that the current one is accepted first and then the one mentioned as after.

Upvotes: 3

Slaw
Slaw

Reputation: 45806

A functional interface must have only one abstract method. However, it can have as many static and default methods as you'd like. The methods of Consumer are:

  1. accept(T)

    • This is the single abstract method of Consumer. It accepts a single generic argument of type T and returns nothing (i.e. void). This is the method that's implemented by a lambda expression or method reference.
  2. andThen(Consumer)

    • This is a default method. In other words, it has an implementation and is thus non-abstract. The method accepts a Consumer and returns another Consumer. Since it's a default method, the single abstract method of Consumer remains accept(T).

The above explains why Consumer can have a method that returns something other than void. Now, when it comes to the implementation of andThen, it's important to realize there are actually three Consumers involved:

  1. The instance on which andThen was invoked.
  2. The instance referenced by after.
  3. The instance returned to the caller.

If you format the code so not everything is on the same line it may be easier to follow:

default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    // Returns Consumer instance #3. The lambda is the implementation
    // of the 'accept' method.
    return (T t) -> {
        accept(t);       // Invokes 'accept' on Consumer instance #1.
        after.accept(t); // Invokes 'accept' on Consumer instance #2.
    }
}

Upvotes: 3

Related Questions