openplanning

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

Xem thêm các chuyên mục:

Hãy theo dõi chúng tôi trên Fanpage để nhận được thông báo mỗi khi có bài viết mới. Facebook

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
  • TODO Link?

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

Xem thêm các chuyên mục: