ランダ式-(2)


標準API


Java 8から標準APIへの関数インタフェースがあり、Consumer、Supplier、Function、Operator、Predicateが含まれています.

Consumer関数インタフェース


名前にはConsumerの関数型インタフェースが含まれています.各メソッドには抽象メソッドaccept()があり、これらのメソッドのシンボルは異なりますが、値は返されません.パラメータのみを受け入れて消費します.異なるタイプのパラメータは、異なるインタフェースを使用します.
インタフェース抽象法Consumervoid Accept BitConsumervoid Accept(T,U)DoubleConsumervoid Accept(二値)LongConsumervoid Accept(LongValue)ObjectDoubleConsumervoid Accept(T,double)ObjectIntConsumerVoid

使用例

Consumer<String> consumer = str -> {
    System.out.println(str);
};

consumer.accept("소비자 인터페이스");

BiConsumer<String, String> biConsumer = (t, u) -> {
    System.out.println(t);
    System.out.println(u);
};

biConsumer.accept("첫번째", "두번째");
宣言consumerの命令文は以下の内容を減らすことができる.一度メソッドを呼び出すのはメソッド本文のすべてだからです.
Consumer<String> consumer = System.out::println;

Supplier関数インタフェース


名前にはSupplierの関数型インタフェースが含まれています.getXXX()という抽象メソッドを持ち、パラメータはなく、戻り値のみです.戻り値のタイプによって、使用するインタフェースが決まります.
インタフェース抽象メソッドSupplierT get

使用例

Supplier<String> supplier = () -> "text";
System.out.println(supplier.get());

DoubleSupplier supplier2 = () -> 1.52;
System.out.println(supplier2.getAsDouble());

ファンクション関数インタフェース


いずれもapplyXXX()というメソッドがあり、パラメータには2つの戻り値があります.主にパラメータを戻り値にマッピングするために使用されます.

オブジェクト->オブジェクト


インタフェース抽象メソッド機能R apply(T)BiFunctionR apply(T,U)

ベーシック->オブジェクト


インタフェース抽象メソッドDoubleFunctionR Apply(二値)IntoFunctionR Apply(intvalue)

入門レベル->入門レベル


インタフェース抽象方法IntoDoubleFunctionデュアルアプリケーション統合プログラム長アプリケーション統合プログラム

オブジェクト->プリミティブ


インタフェース抽象法ToDoubleBiFunctionデュアルアプリケーションDouble(T,U)ToDoubleFunctionデュアルアプリケーションDouble(T,U)ToIntBiFunction

使用例

public class Student {
    private String name;
    
    public Student(String name, int englishScore, int mathScore) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

public class FunctionEx {
    private static List<Student> list = Arrays.asList(
            new Student("신은혁", 100, 95),
            new Student("김연아", 90, 98),
            new Student("차주혁", 80, 92),
            new Student("신주아", 81, 99)
    );

    public static void main(String[] args) {
        Function<Student, String> function = t -> t.getName();
        // 우변을 Student::getName으로 대체 가능
        printString(function);
    }

    public static void printString(Function<Student, String> function){
        for(Student student : list){
            String str = function.apply(student);
            System.out.println("이름 : " + str);
            // 리스트에 있는 각 학생의 이름 출력
        }
        System.out.println();
    }
}

Operator関数インタフェース


Functionとは異なり、ApplyXXX()メソッドには、Functionのようなパラメータと戻り値がありますが、Functionとは異なり、演算を実行した後、戻り値はパラメータと同じタイプを提供します.演算を実行するタイプと被演算者の数に応じて、異なるインタフェースが使用されます.
インタフェース抽象法BinaryOperatorBiFunctionのサブインタフェースUnaryOperatorFunctionのサブインタフェース

使用例

import java.util.function.IntBinaryOperator;

public class OperatorEx {
    public static int[] scores = {15, 55, 10, 100, 92, 35, 87};

    public static void main(String[] args) {
        IntBinaryOperator operatorMax = Math::max;
        System.out.println(maxOrMin(operatorMax)); // 100

        IntBinaryOperator operatorMin = Math::min;
        System.out.println(maxOrMin(operatorMin)); // 10
    }

    public static int maxOrMin(IntBinaryOperator operator){
        int result = scores[0];
        for(int score: scores){
            result = operator.applyAsInt(result, score);
        }

        return result;
    }
}

Predicat関数インタフェース


パラメータとブール型戻り値を有するtestXXX()メソッドがあります.パラメータの値が条件に合っているかどうかを調べ、trueまたはfalseを返します.
インタフェース抽象法PredicatalBell BiPredicatalBell試験(T,U)DoublePredicatalboolean test(DoubleValue)I n t Predicatalboolean test(intvalue)LongPredicatalboolean test(longvalue)
import java.util.ArrayList;
import java.util.function.Predicate;

public class PredicateEx {
    public static ArrayList<Student> arrayList = new ArrayList<>();

    public static void main(String[] args) {
        arrayList.add(new Student("김동년", "여자", 20));
        arrayList.add(new Student("이민기", "남자", 60));
        arrayList.add(new Student("김연아", "여자", 100));
        arrayList.add(new Student("신은혁", "남자", 100));
        arrayList.add(new Student("홍길동", "남자", 80));

        Predicate<Student> predicateMale = student ->
                                   student.getGender().equals("남자");
        Predicate<Student> predicateFemale = student -> 
                                   student.getGender().equals("여자");

        System.out.println(avg(predicateMale));
        System.out.println(avg(predicateFemale));

    }

    public static double avg(Predicate<Student> predicate){
        int count = 0;
        int sum = 0;
        for(Student student: arrayList){
            if(predicate.test(student)){
                count++;
                sum += student.getScore();
            }
        }

        return (double)sum / count;
    }
}

エラーメソッド


関数インタフェースにはandThen()とcompose()というデフォルトのメソッドがあります.

andThen()


2つの関数インタフェースを順次接続して実行します.また,第2の方法のパラメータとして第1の戻り値を用いて最終結果値を返す.
인터페이스AB = 인터페이스A.andThen(인터페이스B);
// 인터페이스A에서의 결과값을 인터페이스B에서의 매개변수로 사용
최종 결과 = 인터페이스AB.method();
// 최종 결과값을 받음

compose()


接続順序がandthen()とは逆の方法.インタフェースBの結果値をインタフェースAのパラメータとして使用し、最終的な結果値を返します.
인터페이스AB = 인터페이스A.compose(인터페이스B);
// 인터페이스B에서의 결과값을 인터페이스A에서의 매개변수로 사용
최종 결과 = 인터페이스AB.method();

Consumer


Consumerインタフェースには戻り値がないため、デバッガメソッドはインタフェースごとに呼び出し順序を設定します.acceptのパラメータは2つの方法で共通に使用される.
Consumer<Person> consumerA = person -> 
    System.out.println("ConsumerA : " + person.getName());
Consumer<Person> consumerB = person -> 
    System.out.println("ConsumerB : " + person.getId());

Consumer<Person> consumerAB = consumerA.andThen(consumerB);
consumerAB.accept(new Person("김남건", "Kim", null));

Function


先に実行したメソッドの結果値を次のメソッドのパラメータに渡し、最終値を返します.
andThenでもcomposeでも、2番目の呼び出しメソッドのパラメータタイプは、1番目の呼び出しメソッドが返す値のタイプと一致する必要があります.
Function<Person, Address> functionA = p -> p.getAddress();
Function<Address, String> functionB = a -> a.getCountry();

Function<Person, String> functionAB = functionA.andThen(functionB);
String country = functionAB.apply(new Person("김남건", "kim", 
    new Address("한국", "제주")));
System.out.println(country);

インタフェース別の方法



Predicatのデフォルトメソッド


Predicateはブール型の値を返すため、and()、or()、negate()の3つの方法があります.この3つの方法は、すべてのPredicatインタフェースでサポートされています.また,静的手法isEqual()もサポートする.

and()


両方のPredicateがtrueを返すと、最終的にtrueが返されます.
predicateAB = predicateA.and(predicateB);

or()


両方がtrueの場合、最終的にtrueが返されます.
predicateAB = predicateA.or(predicateB);

negate()


Predicatの結果とは逆の値を返します.
predicateB = predicateA.negate();

IntPredicate predicateA = x -> x % 2 == 0;
IntPredicate predicateB = x -> x % 3 == 0;
IntPredicate predicateAB = predicateA.and(predicateB);
System.out.println("36은 6의 배수인가? : " + predicateAB.test(36));

IntPredicate predicateC = predicateA.negate();
System.out.println("21은 홀수인가? : " + predicateC.test(21));

Predicate.isEqual()


既存のオブジェクト.equals()メソッドの機能は,空の値を比較する機能も追加した.返される値はPredicatなのでtest()を呼び出さなければなりません.
sourceObjecttargetObject戻り値nullNull TrueNot nullFallFallNull Not nullTrueNot nullNot nullSourceObject.equals(targetObject)
Predicate<String> predicate = Predicate.isEqual("문자열1");
boolean result1 = predicate.test("문자열1");
boolean result2 = predicate.test(null);
System.out.println(result1); // true
System.out.println(result2); // false

BinaryOperatorのデフォルトメソッド


minBy(), maxBy()


最大Tと最小Tを取得したBinaryOperatorをComparatorを使用して返します.どちらも静的方法です.
戻りメソッドBinaryOperatorminBy(Comparator<スーパーT>Comparator)BinaryOperatormaxBy(Comparator<スーパーT>Comparator)

使用例

BinaryOperator<Fruit> binaryOperator = 
    BinaryOperator.minBy((f1, f2) -> f1.getPrice() - f2.getPrice());

Fruit fruit = binaryOperator.apply(new Fruit("황도", 5000),
    new Fruit("복숭아", 4000));
System.out.println(fruit.getName()); // 복숭아

メソッド参照


ラムダ式は、既存のメソッドのみを呼び出す場合があります.この場合,コードをより簡潔にするために導入されるのはメソッドリファレンスである.ramda式でパラメータまたはメソッド本文を記述するよりも、メソッド呼び出しの代わりにメソッド名のみを書くこともできます.
IntBinaryOperator operator = (a, b) -> Math.max(a, b);
IntBinaryOperator operator = Math::max;

スタティツクメソッド


静的メソッド(クラス名):(メソッド).
IntBinaryOperator operator = (a, b) -> Math.max(a, b);
IntBinaryOperator operator = Math::max;

インスタンスメソッド


(参照変数):(メソッド)形式で呼び出されます.
public class Calculator{
    public int method(int x, int y){
        return x + y;
    }
}

Calculator cal = new Calculator();
Operator operator = cal::method;
System.out.println(operator.applyAsInt(7, 8));

ジェネレータを参照


(クラス):new参照として使用します.インタフェースのメソッドを呼び出すと、パラメータの数、タイプに応じて他のジェネレータが呼び出されます.
public class Person {
    private String name;
    private int age;

    public Person(){
        System.out.println("기본생성자 호출");
    }

    public Person(String name){
        System.out.println("String name 받는 생성자 호출");
        this.name = name;
    }

    public Person(String name, int age) {
        System.out.println("매개변수 두개 받는 생성자 호출");
        this.name = name;
        this.age = age;
    }
}

public class PersonEx {
    public static void main(String[] args) {
        Function<String, Person> function1 = Person::new;
        Person person1 = function1.apply("신은혁");

        BiFunction<String, Integer, Person> function2= Person::new;
        Person person2 = function2.apply("김남건", 25);
    }
}