openplanning

Hướng dẫn và ví dụ Java Consumer

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

1. Consumer

Trong Java 8, Consumer là một functional interface, đại diện cho một toán tử chấp nhận một tham số đầu vào và không trả về gì cả.
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);
        };
    }
}
Ví dụ:
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
    }
}
Mở rộng ví dụ trên, chúng ta sử dụng Consumer trong phương thức 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
Dưới đây là danh sách các phương thức trong package java.util sử dụng 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)
Xem thêm: BiConsumer là một functional interface tương tự như Consumer, điều khác biệt là nó chấp nhận 2 tham số:

2. Consumer + Method reference

Nếu một phương thức có một tham số duy nhất và không trả về gì cả, thì tham chiếu của nó sẽ được coi là một Consumer.
Ví dụ: Phương thức System.out.println(param) có một tham số và không trả về gì cả, thì tham chiếu (reference) của nó là System.out::println sẽ được coi như một 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!
Ví dụ:
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

Phương thức andThen(after) trả về một Consumer kết hợp. Đầu tiên, Consumer hiện tại sẽ được gọi sau đó after sẽ được gọi. Nếu lỗi xẩy ra tại một trong 2 bước trên lỗi sẽ được chuyển tới người gọi (caller). Nếu lỗi xẩy ra tại Consumer hiện tại thì after bị bỏ qua.
Consumer
default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return (T t) -> {
       accept(t);
       after.accept(t);
    };
}
Ví dụ:
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");
    }
}
Kết quả là chữ "hello" đã được in ra 2 lần:
hello
hello
Ví dụ:
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 cơ bản

Show More