핵심정리 1: 람다 vs 메서드 참조 (Reference)

메서드 이름이 보다 읽기 쉽다면 -> 메서드 레퍼런스

매개변수 이름이 보다 읽기 쉽고 의미를 잘 표현한다면 -> 람다

메서드와 람다가 같은 클래스에 있을 때는 -> 람다

람다로 작성할 코드를 새로운 메서드로 담은 다음, 람다 대신 메서드 참조를 사용 하기.

// map.merge를 이용해 구현한 빈도표 - 람다 방식과 메서드 참조 방식을 비교해보자. (259쪽)
public class Freq {
    public static void main(String[] args) {
        args = new String[] {"hello", "keesun"};
        Map<String, Integer> frequencyTable = new TreeMap<>();
        
        for (String s : args)
        // 값이 없으면 1 값이 있으면 +1 씩 증가하는 코드 
            **frequencyTable.merge(s, 1, (count, incr) -> sum(count, incr)); // 람다**
        System.out.println(frequencyTable);

        frequencyTable.clear();
        for (String s : args)
            **frequencyTable.merge(s, 1, Integer::sum); // 메서드 참조**
        System.out.println(frequencyTable);
    }
		// 람다로 작성할 코드를 새로운 메서드로 담은 다음, 람다 대신 메서드 참조를 사용 
    **private static Integer sum(Integer count, Integer incr) {
        return count + incr;
    }**
}

핵심정리 2: 다섯 가지 메서드 참조 (Reference)

image.png

  1. 정적 메서드 참조 예제

    public class **StaticMethodReference** {
    
        public static void main(String[] args) {
            List<String> words = new ArrayList<>(Arrays.asList("aaa", "bbbbb", "c"));
            System.out.println("Before sorting: " + words);
    
            // 정적 메서드 참조
            Collections.sort(words, **StaticMethodReference::compareByLength);**
    
            System.out.println("After sorting: " + words);
        }
    
        public static int **compareByLength**(String s1, String s2) {
            return Integer.compare(s1.length(), s2.length());
        }
    }
    
    
  2. 한정적인 메서드 참조 예제

    public class BoundedMethodReference {
        public static void main(String[] args) {
            List<Instant> instants = new ArrayList<>();
            instants.add(Instant.now().minusSeconds(10));
            instants.add(Instant.now().plusSeconds(10));
            instants.add(Instant.now().minusSeconds(20));
            instants.add(Instant.now().plusSeconds(20));
    
            **Instant now = Instant.now();**
    
            // 한정적 메서드 참조
            List<Instant> futureInstants = instants.stream()
                    **.filter(now::isAfter)**
    //                .filter(t -> now.isAfter(t))
                    .toList();
    
            System.out.println("Future instants: " + futureInstants);
        }
    }
    
    
  3. 비한정적인 메서드 참조 예제

    public class UnboundedMethodReference {
        public static void main(String[] args) {
            List<String> words = new ArrayList<>(Arrays.asList("Banana", "Apple", "Cherry"));
            System.out.println("Before conversion: " + words);
    
            // 비한정적 메서드 참조 1
            List<String> lowerCaseWords = words.stream()
                    **.map(String::toLowerCase)**
    //                .map(s -> s.toLowerCase())
                    .toList();
    
            System.out.println("After conversion: " + lowerCaseWords);
    
            words = new ArrayList<>(Arrays.asList("banana", "apple", "cherry"));
            System.out.println("Before sorting: " + words);
    
            // 비한정적 메서드 참조 2
            **Collections.sort(words, String::compareTo);**
    //        Collections.sort(words, (s1, s2) -> s1.compareTo(s2));
    
            System.out.println("After sorting: " + words);
    
        }
    }
    
    
  4. 클래스 생성자 예제

    public class ConstructorMethodReference {
        public static void main(String[] args) {
            List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
            System.out.println("Names: " + names);
    
            // 생성자 참조
            List<Person> people = names.stream()
                    **.map(Person::new)**
    //                .map(name -> new Person(name))
                    .toList();
    
            System.out.println("People: " + people);
        }
    }
    
    
  5. 배열 생성자 예제

    public class ArrayConstructorMethodReference {
        public static void main(String[] args) {
            List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
            System.out.println("Names: " + names);
    
            // 배열 생성자 참조
            String[] namesArray = names.toArray(String[]::new);
    
            System.out.println("Names array: " + Arrays.toString(namesArray));
        }
    }