[JAVA8] Consumer, Supplier, Predicate 및 Function의 신속한 이해

7055 단어 #Java8 기능

Consumer, Supplier, Predicate 및 Function의 신속한 이해


1. 앞말


이 몇 개의 인터페이스는 모두java에 있다.util.기능 패키지 아래 Consumer(소비형), Supplier(공급형), Predicate(판단형)와 Function(전환형)은 당분간 그들의 유형을 이해하지 못해도 상관없다.
만약에 Lambda를 잘 이해하지 못하는 학생이라면 먼저 나의 다른 문장으로 옮겨서 Lambda에 대한 이해를 할 수 있다

2. Consumer


Consumer는 소비형 인터페이스로 하나를 받고 이 수박을 소비하는데 수박씨도 남기지 않는다.
먼저 Consumer 인터페이스의 원본을 보면 실현되지 않은 추상적인 방법과 기본적인 방법(jdk1.8 이후 인터페이스에 기본적인 방법과 정적 방법이 있을 수 있음)이 있습니다.
@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); };
    }

}

우리는 이 accept 방법에만 신경을 쓰고 일반적인 매개 변수를 수신하며 어떤 값도 되돌려 주지 않습니다.ok, 우리 간단하게 실현합시다
        Consumer consumer=new Consumer() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        };

        consumer.accept(1);
    }

자, 발가락으로 생각하면 틀림없이 출력 1이 될 거야.
다음은 익명 내부 클래스를 수정하기 위해lambda 표현식을 사용합니다.이때 이 lambda의 유형은 Consumer 유형입니다.
    consumer=i-> System.out.println(i);

물론 우리도 방법을 써서 인용할 수 있다
    consumer=System.out::println;

Stream 클래스에서 자주 사용하는 forEach 인터페이스가 Consumer 유형의 매개 변수를 수신하는 것을 발견했습니다. 원본은 다음과 같습니다.
    void forEach(Consumer super T> action);

두 마디로 말하자면, 우리는consumer를forEach에 전송하여, 집합을 반복하는 작업을 실현할 것이다.
        List list= Arrays.asList(1,2,3,4,5);
        Consumer consumer= System.out::println;
        list.stream().forEach(consumer);

중간consumer 대상을 없애면 코드가 더욱 간결해진다.어, 여기까지 온 것 같지 않아? 알고 보니 이렇게 변했구나.
        List list = Arrays.asList(1, 2, 3, 4, 5);
        list.stream().forEach(System.out::println);

Consumer 요약:
Consumer 인터페이스는 소비형 인터페이스로 accept 방법만 실현하면 소비자로서 정보를 출력할 수 있습니다
lambda, 메서드 참조는 모두 하나의 Consumer 유형일 수 있기 때문에 그들은 forEach의 매개 변수로 Stream에서 정보를 출력하는 데 도움을 줄 수 있다..
Consumer에는 아직도 많은 변종이 있다. 예를 들어 Int Consumer, Double Consumer와 Long Consumer 등이다. 결국 이런 변종은 사실 Consumer의 범주형을 지정했을 뿐 방법에 변화가 없다

3. Supplier


Supplier는 공급형 인터페이스입니다. 우리는 무조건 여기에서 물건을 얻을 수 있습니다.
@FunctionalInterface
public interface Supplier {

    T get();
}

우리는 get 방법을 위해 어떤 매개 변수도 전송할 필요가 없다. 결과를 얻을 수 있다. 이것은 오입질이 아닌가?그럼 저는 랜덤으로 세고 싶어요.
        Supplier supplier=()->new Random().nextDouble();
        // 
        Supplier supplier1= Math::random;
        System.out.println(supplier.get());

다음 단계, Supplier는 어떤 곳을 할 수 있습니까? 어쨌든 오입질을 할 수 있기 때문에 누가 좋아하지 않겠습니까?Supplier의 Optional 활용 사례를 살펴보겠습니다.
    public T orElseGet(Supplier extends T> other) {
        return value != null ? value : other.get();
    }

이 방법은 Supplier 유형의 매개 변수를 수신하고 Optional 내부의 value가 비어 있지 않으면 Supplier의 값을 되돌려줍니다.예:
        Optional optional=Optional.empty();
        Supplier supplier=()->new Random().nextDouble();
        optional.orElseGet(supplier);

이것은 옵션이기 때문에 Supplier의 임의 값을 반환합니다.empty () 에 포함된 값은null입니다.
Supplier 요약:
Supplier는 하나의 값을 되돌려 주는 데 사용되는 공급형 인터페이스입니다
Supplier에도 많은 변종이 있는데, 예를 들면 Int Supplier, Long Supplier와 Boolean Supplier 등이다

4. Predicate


Predicate는 원본 코드를 볼 수 있는 판단형 인터페이스입니다.
@FunctionalInterface
public interface Predicate {

    boolean test(T t);

    default Predicate and(Predicate super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate negate() {
        return (t) -> !test(t);
    }

    default Predicate or(Predicate super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    static  Predicate isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

이 인터페이스는 jdk1.8에서 인터페이스의 변화를 생생하게 보여준다. 인터페이스는 더 이상'순수하지 않다'. 기본적인 방법과 정적 방법이 있을 수 있다. 다음 면접에서 다시 물어보면 득점 상황을 보고 울음을 터뜨린다.
인터페이스를 이해하려면 우리는 그것을 실현하는 방법을 찾아야 한다.
        Predicate predicate=i->i>5;
        System.out.println(predicate.test(1));

출력은false입니다.잠깐만, 판단을 할 수 있는 이상, 그것과 Stream.filter () 괜찮아요?
    Stream filter(Predicate super T> predicate);

역시 상관이야, , 이 날카로운 후각.그러면 Predicate 객체를 filter에 전송해 볼까요?
        List list= Arrays.asList(1,2,3,4,5,6,7,8);
        list.stream().filter(i->i>5).forEach(System.out::print);

간단합니다. 출력은 678입니다.
Predicate 요약:
Predicate는 테스트 방법으로 전송된 매개 변수를 테스트하는 판단형 인터페이스입니다
물론 Predicate에도 대응하는 변종이 있습니다..

5. Function


Function은 하나의 유형의 데이터를 다른 유형의 데이터로 바꾸는 기능적인 인터페이스입니다.
@FunctionalInterface
public interface Function {

    R apply(T t);

    default  Function compose(Function super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default  Function andThen(Function super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static  Function identity() {
        return t -> t;
    }
}

그것의 apply 방법에 중점을 두고 지금 그것을 실현하고 이를 Stream으로 전달합니다.맵 () 방법에서 시도해 보세요.
public class TestFunction {
    static class Student{
        String name;
        Integer id;

        public Student(String name, Integer id) {
            this.name = name;
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public Integer getId() {
            return id;
        }
    }
    public static void main(String[] args) {
        List list= Arrays.asList(new Student("jack",1),new Student("tom",2));
        Function function= Student::getId;
        list.stream().map(function).forEach(System.out::print);
    }
    
}

출력 12에서 알 수 있듯이 Function의 apply 방법은 Student 형식의 데이터를 id에 대응하는 Integer 형식의 데이터로 전환시킨다.
Function 요약:
Function은 하나의 변환형 인터페이스로 그 중의 apply는 하나의 유형의 데이터를 다른 유형의 데이터로 전환할 수 있다..
Function의 변종이 더 많아졌어요.

6. 총결산


우선 이 네 개의 인터페이스 유형, Consumer(소비형), Supplier(공급형), Predicate(판단형), Function(전환형)만 기억하면
그에 대응하는 추상적인 방법인 Consumer(accpet), Supplier(get), Predicate(test), Function(apply)을 기억하십시오.

좋은 웹페이지 즐겨찾기