모르지 않다는 것은 아는것과 다르다.

Java

Method Reference

채마스 2022. 3. 6. 23:35

Method Reference

  • 기존에 이미 선언된 메소드를 지정하고 싶을 때 사용한다.
  • :: 오퍼레이터를 사용한다.
  • 생략되는 부분이 많기 때문에 사용할 메소드의 매개변수의 타입과 리턴 타입을 미리 숙지해야한다.

 

Method Reference 의 4가지 케이스

  1. ClassName::staticMethodName (클래스의 static Method 를 지정할 때)
  2. ObjectName::instanceMethodName (선언된 객체의 instance method 를 지정할 때)
  3. ClassName::instanceMethodName (객체의 instance method를 지정할 때)
  4. ClassName::new (클래스의 constructor를 지정할 때)

 

ClassName::staticMethodName (클래스의 static Method 를 지정할 때)

public class MethodReferenceTypeOne {

    public static int calculate(int x, int y, BiFunction<Integer, Integer, Integer> operator) {
        return operator.apply(x, y);
    }

    public static int multiply(int x, int y) {
        return x * y;
    }


    public static void main(String[] args) {
        Function<String, Integer> str2int = Integer::parseInt;
        System.out.println(str2int.apply("20"));

        System.out.println(calculate(8, 2, (x, y) -> x + y)); // BiFuction으로 인자 전달
        System.out.println(calculate(8, 2, MethodReferenceTypeOne::multiply));

    }
}
  • calculate 메소드의 세번째 인자는 BiFunction<Integer, Integer, Integer> 이다. -> 그렇기 때문에 Integer 타입의 인자 2개를 받아서 Integer 타입 1개를 반환하는 multiply 메소드를 변수로 받을 수 있다.

 

ObjectName::instanceMethodName (선언된 객체의 instance method 를 지정할 때)

public class MethodReferenceTypeTwo {

    public static int calculate(int x, int y, BiFunction<Integer, Integer, Integer> operator) {
        return operator.apply(x, y);
    }

    public int subtract(int x, int y) {
        return x - y;
    }

    public void myMethod() {
        System.out.println(calculate(10, 3, this::subtract));
    }


    public static void main(String[] args) {

        String str = "hello";
        Predicate<String> equalsToHello = str::equals;
        System.out.println(equalsToHello.test("world"));

        MethodReferenceTypeOne instance = new MethodReferenceTypeOne();
        System.out.println(calculate(8, 2, instance::subtract));
        instance.myMethod();
    }

}

 

ClassName::instanceMethodName (객체의 instance method를 지정할 때)

public class MethodReferenceTypeThree {

    public static void main(String[] args) {
        Function<String, Integer> strLength = String::length; // instance method 이다.
        int length = strLength.apply("hello world");
        System.out.println(length);

        BiPredicate<String, String> strEquals = String::equals;
        boolean helloEqualsWorld = strEquals.test("hello", "world");
        System.out.println(strEquals.test("hello", "hello"));

        List<User> users = new ArrayList<>();
        users.add(new User(3, "Alice"));
        users.add(new User(1, "Charlie"));
        users.add(new User(5, "Bob"));

        printUserField(users, User::getName);
    }

    public static void printUserField(List<User> users, Function<User, Object> getter) {
        for (User user : users) {
            System.out.println(getter.apply(user));
        }
    }
}
  • String 2개를 인자로 받아서 값을 비교하기 때문에 반환 타입이 BiPredicate<String, String> 으로 String::length를 받는다.

 

ClassName::new (클래스의 constructor를 지정할 때)

public class MethodReferenceTypeFour {

    public static void main(String[] args) {
        Map<String, BiFunction<String, String, Car>> carTypeToConstructorMap = new HashMap<>();
        carTypeToConstructorMap.put("sedan", Sedan::new);
        carTypeToConstructorMap.put("suv", Suv::new);
        carTypeToConstructorMap.put("van", Van::new);

        User user = new User(1, "Alice");
        BiFunction<Integer, String, User> userCreator = User::new;
        User charlie = userCreator.apply(3, "Charlie");
        System.out.println(charlie);

        String[][] inputs = new String[][] {
            { "sedan", "Sonata", "Hyundai" },
            { "van", "Sienna", "Toyota" },
            { "sedan", "Model S", "Tesla" },
            { "suv", "Sorento", "KIA" }
        };

        List<Car> cars = new ArrayList<>();
        for (int i = 0; i < inputs.length; i++) {
            String[] input = inputs[i];
            String carType = input[0];
            String name = input[1];
            String brand = input[2];

            cars.add(carTypeToConstructorMap.get(carType).apply(name, brand));
        }

        for (Car car : cars) {
            car.drive();
        }
    }

}
  • User 의 생성자가 인자 2개를 받아서 객체를 생성하므로 Integer와 String 을 인자로 받아서 User 를 반환할 수 있는 타입인 BiFunction<Integer, String, User> 타입으로 User::new 생성자를 받는다.




 

REFERENCES

  • 이승환님의 JAVA Stream

'Java' 카테고리의 다른 글

@SuppressWarnings  (0) 2022.05.30
ENUM 활용  (0) 2022.03.14
Collectors (JAVA STREAM)  (0) 2022.03.06
LazyEvaluation,Curry,IntStream  (0) 2022.03.06
Stream 응용  (0) 2022.03.06