betacode

Руководство Java Consumer

  1. Consumer
  2. Consumer + Method reference
  3. Consumer.andThen

1. Consumer

В Java 8, Consumer - это functional interface, представляющий оператор, который принимает входной параметр и ничего не возвращает.
Consumer
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> {
            accept(t);
            after.accept(t);
        };
    }
}
Например:
ConsumerEx1.java
package org.o7planning.ex;

import java.util.function.Consumer;

public class ConsumerEx1 {
    
    public static void main(String[] args)  {

        // Create a Consumer object directly
        Consumer<String> greeter = name -> System.out.println("Hello " + name);
        
        greeter.accept("Tran");   // Hello Tran
    }
}
Расширяя приведенный выше пример, мы используем Consumer в методе Stream.forEach.
// A method of Stream class
public void forEach(Consumer<? super T> action);
ConsumerEx2.java
package org.o7planning.ex;

import java.util.function.Consumer;
import java.util.stream.Stream;

public class ConsumerEx2 {
    
    public static void main(String[] args)  {

        // Create a Consumer object directly
        Consumer<String> greeter = name -> System.out.println("Hello " + name);  
        
        Stream<String> names = Stream.of("Tran", "Nguyen", "Pham");
        
        names.forEach(greeter);
    }
}
Output:
Hello Tran
Hello Nguyen
Hello Pham
Ниже приведен список методов в пакете java.util, использующих Consumer:
Modifier and Type
Method and Description
void
ArrayList.forEach(Consumer<? super E> action)
void
Vector.forEach(Consumer<? super E> action)
default void
PrimitiveIterator.OfDouble.forEachRemaining(Consumer<? super Double> action)
default void
Spliterator.OfDouble.forEachRemaining(Consumer<? super Double> action)
default void
Iterator.forEachRemaining(Consumer<? super E> action)
default void
PrimitiveIterator.OfInt.forEachRemaining(Consumer<? super Integer> action)
default void
Spliterator.OfInt.forEachRemaining(Consumer<? super Integer> action)
default void
PrimitiveIterator.OfLong.forEachRemaining(Consumer<? super Long> action)
default void
Spliterator.OfLong.forEachRemaining(Consumer<? super Long> action)
default void
Spliterator.forEachRemaining(Consumer<? super T> action)
void
Optional.ifPresent(Consumer<? super T> consumer)
default boolean
Spliterator.OfDouble.tryAdvance(Consumer<? super Double> action)
default boolean
Spliterator.OfInt.tryAdvance(Consumer<? super Integer> action)
default boolean
Spliterator.OfLong.tryAdvance(Consumer<? super Long> action)
boolean
Spliterator.tryAdvance(Consumer<? super T> action)
См. также: BiConsumer - это functional interface, похожий на Consumer. Разница в том, что он принимает 2 параметра:

2. Consumer + Method reference

Если метод имеет один параметр и ничего не возвращает, его ссылку можно считать Consumer.
Например: метод System.out.println(param) принимает один параметр и ничего не возвращает, тогда его ссылка System.out::println будет рассматриваться как Consumer.
ConsumerEx5.java
package org.o7planning.ex;

import java.util.function.Consumer;

public class ConsumerEx5 {

    public static void main(String[] args) {

        myPrintln(System.out::println, "Hello World!");
    }
    
    public static <T> void myPrintln(Consumer<T> c, T t) {
         c.accept(t);
    }
}
Output:
Hello World!
Например:
ConsumerEx6.java
package org.o7planning.ex;

import java.util.stream.Stream;

public class ConsumerEx6 {

    public static void main(String[] args) {
        
        Stream<String> names = Stream.of("Tran", "Nguyen", "Pham");
        
        // Call method: Stream.forEach(Consumer)
        names.forEach(System.out::println);
    }
    
}
Output:
Tran
Nguyen
Pham

3. Consumer.andThen

Метод andThen(after) возвращает ассоциированный Consumer . Сначала будет вызван текущий Consumer, а затем будет вызван after. Если на одном из двух вышеперечисленных шагов возникает ошибка, она передается вызывающему абоненту (caller). Если ошибка возникает у текущего Consumer, то after игнорируется.
Consumer
default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return (T t) -> {
       accept(t);
       after.accept(t);
    };
}
Например:
ConsumerEx3.java
package org.o7planning.ex;

import java.util.function.Consumer;

public class ConsumerEx3 {
    
    public static void main(String[] args)  {
        
        Consumer<String> c = text -> System.out.println(text.toLowerCase());   
         
        c.andThen(c).accept("Hello");
    }
}
В результате слово "hello" было напечатано дважды.
hello
hello
Например:
ConsumerEx4.java
package org.o7planning.ex;

import java.util.function.Consumer;

public class ConsumerEx4 {

    public static void main(String[] args) {

        Consumer<UserAccount> c1 = test -> test.auth();

        Consumer<UserAccount> c2 = test -> test.welcome();

        UserAccount user = new UserAccount("tran", "123");

        try {
            c1.andThen(c2).accept(user);
        } catch (Exception e) {

        }
    }

    public static class UserAccount {
        private String userName;
        private String password;

        public UserAccount(String userName, String password) {
            this.userName = userName;
            this.password = password;
        }

        public void auth() {
            if ("123".equals(password)) {
                System.out.println("Valid Account!");
            } else {
                throw new RuntimeException("Invalid Password");
            }
        }

        public void welcome() {
            System.out.println("Welcome! " + this.userName);
        }
    }
}
Output:
Valid Account!
Welcome! tran

Java Basic

Show More