자바 상용 함수 인터페이스 - Consumer 인터페이스

5561 단어 자바functionstream
JDK 는 대량의 함수 식 인 터 페 이 스 를 제공 하여 우리 가 개발 할 때 인 터 페 이 스 를 직접 만 들 필요 가 없다. 이런 인 터 페 이 스 는 모두 통용 되 고 그들 을 배 워 서 업무 중 에 사용 할 수 있 으 며 문 제 를 편리 하 게 해결 할 수 있 을 뿐만 아니 라 매우 우아 하 다.
1. 인터페이스 개요Consumer 인터페이스 도 비교적 간단 하 다. 두 가지 방법 만 있 고 하 나 는 추상 적 인 방법 이 며 하 나 는 기본 적 인 방법 이다.
@FunctionalInterface
public interface Consumer {

    void accept(T t);

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

2. accept 방법
이 방법 은 인터페이스 범 형 형식의 대상 을 받 아들 여 반환 값 이 없습니다.
집합 forEach 방법의 사용 을 살 펴 보 자.
public class ConsumerTest {
    public static void main(String[] args) {
        List names = new ArrayList() {
            {
                add("Tom");
                add("Jerry");
            }
        };
        names.forEach(e -> System.out.println(e));
        names.forEach(System.out::println);
    }
}

우리 가 forEach 방법 을 사용 할 때 이 방법 은 Consumer 인 터 페 이 스 를 매개 변수 로 사용 한 것 이다.이것 은 우리 가 가장 흔히 볼 수 있 는 사용 Consumer 방식 이다.
인쇄 정 보 를 제외 하고 일반적으로 우 리 는 집합 중인 대상 의 일부 데 이 터 를 변경 해 야 하 며, foreach 를 자주 사용 한 다음 에 모든 대상 에 대해 업무 작업 을 합 니 다.
비록 forEach 자주 사용 되 지만 보통 우 리 는 forEach 의 실현 에 관심 이 없고 스스로 방법 을 써 서 Consumer 인 터 페 이 스 를 사용 하 는 경우 도 적다.
    default void forEach(Consumer super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

3. 소비자 인터페이스 사용 장면 - 리 셋
public class ConsumerTest {

    private static final Map map = new HashMap() {
        {
            put(10, "Tom");
            put(3, "Jerry");
        }
    };

    public static void main(String[] args) {
        //调用方法,同时编写对结果的回调:此处仅仅打印而已
        test(3, System.out::println);
    }

    public static void test(Integer age, Consumer consumer) {
        //业务处理
        System.out.println(age);

        //对处理结果的回调:下面的ifPresent参数也是Consumer接口,所有下面三种写法都可以
        //Optional.ofNullable(map.get(age)).ifPresent(e -> consumer.accept(e));
        //Optional.ofNullable(map.get(age)).ifPresent(consumer::accept);
        Optional.ofNullable(map.get(age)).ifPresent(consumer);
    }
}
Consumer 인 터 페 이 스 는 일반적으로 방법 매개 변수 로 리 셋 기능 을 실현 한다. 예 를 들 어 위의 예, test 함수 가 처리 대상 age 을 전달 하고 업무 처 리 를 통 해 다른 결과 대상 을 얻 은 후에 호출 accept 하여 결과 대상 을 처리한다.
실제 리 셋 처리 대상 은 입 참 에 따라 다른 결 과 를 얻 는 것 이다.예 를 들 어 데이터베이스 에서 데 이 터 를 조회 하고 리 셋 함수 가 데 이 터 를 다른 곳 에 저장 하면 이 다른 곳 은 호출 자가 스스로 처리 해 야 한다. 예 를 들 어 파일 을 저장 하 는 것 이다.
4, 기본 방법 and Then
방법 원본:
    default Consumer andThen(Consumer super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }

사용 필드:
    public static void main(String[] args) {
        Consumer first = (x) -> System.out.println(x.toLowerCase());
        Consumer next = (x) -> System.out.println(x.toUpperCase());
        first.andThen(next).accept("Hello World");
    }

and Then 은 Consumer 인 터 페 이 스 를 받 고 되 돌아 오 는 것 도 Consumer 인터페이스 입 니 다. 마찬가지 로 이 방법 을 호출 하 는 것 도 Consumer 인터페이스 입 니 다.이곳 은 비교적 돌아 서 위의 두 코드 를 대조 하여 자세하게 분석 해 야 한다.first 는 하나의 Consumer 인터페이스 로 andThen 방법 을 호출 할 때 (T t) -> { accept(t); after.accept(t); } 코드 를 실행 하 는 것 이 아니 라 Consumer 인 터 페 이 스 를 되 돌려 주 었 다. 그 구 조 는 대상 t 에 게 주 고 괄호 에서 t 를 소비 하 는 것 임 을 주의해 야 한다.처리 논 리 는 현재 Consumer 집행 accept 방법 이 고 afterConsumer 집행 accept 방법 이다.이해 andThen 방법 이 되 돌아 오 는 구 조 는 특히 중요 하 다.first.andThen(next) 실행 이 완료 되 었 을 때 Consumer 인터페이스 인 터 페 이 스 를 얻 은 후에 다시 호출 accept("Hello World") 할 때 실제 Hello World 문자열 에 실 행 된 내용 은 대괄호 안의 내용 입 니 다. accept(t); after.accept(t); 즉, 위의 소문 자 문자열 을 먼저 출력 하고 대문자 문자열 을 출력 하 는 것 입 니 다.
5 、 and Then 방법 사용 장면
public class ConsumerTest {

    private static final Map> QUEUE = new ConcurrentHashMap<>();

    public static void main(String[] args) {
        resolve(1, s -> System.out.println(s.toUpperCase()));
        resolve(1, s -> System.out.println(s.toLowerCase()));
        resolve(1, s -> System.out.println(s.substring(0, 2)));
        QUEUE.get(1).accept("Hello World");
    }

    public static void resolve(Integer id, Consumer callback) {
        final Consumer existing = QUEUE.get(id);
        if (callback == null) callback = i -> {};
        if (existing != null && callback != existing) {
            callback = existing.andThen(callback);
        }
        QUEUE.put(id, callback);
    }
}

결 과 는 다음 과 같다.
HELLO WORLD
hello world
He
위 코드 의 resolve 방법 은 id 에 따라 map 형식의 QUEUE 에 여러 개의 리 셋 함 수 를 추가 하고 마지막 에 실 행 될 때 여러 개의 리 셋 함수 가 모두 실 행 됩 니 다. 책임 체인 의 디자인 모델 과 유사 합 니 다.위의 설명 과 결합 하여 자세히 이해 할 수 있다.
callback = existing.andThen(callback);

그리고 실행 중인 곳:
QUEUE.get(1).accept("Hello World");

좋은 웹페이지 즐겨찾기