몽-구
몽구의 우당탕탕 개발 공부
몽-구
전체 방문자
오늘
어제
  • 분류 전체보기 (106)
    • PS (38)
      • 백준 (24)
      • 프로그래머스 (14)
    • Dev (58)
      • Kotlin (0)
      • Java (4)
      • Spring, SpringBoot (1)
      • C (8)
      • Python (10)
      • Dart (1)
      • 알고리즘 (7)
      • 자료구조 (3)
      • Git (1)
      • Linux (2)
      • VS Code (1)
      • 환경 설정 (8)
      • Conference (1)
      • 42Seoul (3)
      • Node.js (1)
      • ShellScript (1)
      • IntelliJ (0)
      • MacOS (2)
      • 기타 (3)
    • CS (1)
      • 데이터베이스 (1)
    • DS (4)
      • Coursera (4)
    • 리뷰 (1)
      • 제품 리뷰 (1)
    • 일상 (3)
      • 자동화 (1)
      • 목표 및 계획 (2)
      • 회고 (0)
    • 삶에 대한 태도 (1)
      • 유튜브를 보며 (1)

블로그 메뉴

  • GitHub

인기 글

반응형

태그

  • 백준
  • 알고리즘
  • BOJ
  • Python
  • 코딩테스트
  • sort
  • 백준온라인저지
  • 리눅스
  • 프로그래머스
  • 파이썬
  • Linux
  • Algorithm
  • 정렬
  • 백준알고리즘
  • c언어

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
몽-구

몽구의 우당탕탕 개발 공부

[Java] 람다식에서 메서드 참조/생성자 참조 사용법
Dev/Java

[Java] 람다식에서 메서드 참조/생성자 참조 사용법

2021. 3. 19. 10:13
반응형

들어가며

Java 8 이상에서 람다식을 사용할 때 콜론 2개를 사용하는 경우가 있습니다. 이를 메서드 참조(Method Reference) 혹은 이중 콜론 연산자(::)라고 표현하는데요. 정식 명칭은 메서드 참조입니다. 그러면 메서드 참조는 어떨 때 사용할 수 있는 것인지, 그리고 어떻게 사용하는 것인지 간단하게 알아보겠습니다.

 

 

 

메서드 참조는 언제, 어떻게 사용할 수 있을까

메서드 참조는 람다식에서 파라미터의 중복을 피하기 위해 사용합니다. 파라미터가 중복되지 않았다면 메서드 참조 표현식은 사용 불가능합니다. 코드로 바로 보겠습니다.

 

인스턴스의 메서드를 참조하는 경우

public class Main {
    public static void main(String[] args) {
        List<Member> memberList = Arrays.asList(new Member("A"), new Member("B"), new Member("C"));
        String collect = memberList.stream().map(element -> element.getName()).collect(Collectors.joining());
        System.out.println(collect);
    }

    public static class Member {
        private String name;

        public Member(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }
}

 

위 코드에서 stream 생성 이후 map 메서드에서 람다식을 사용했습니다. 이때 map에 걸리는 요소들은 Member 인스턴스죠. 그리고 map 내부에서 인스턴스의 메서드인 getName()을 호출하고 있습니다.

 

그런데 문제는 요소를 지칭하는 element가 두 번이나 등장합니다. Java에서는 이게 보기 싫었던 겁니다. 이걸 꼭 한 번만 써주고 싶었던 것이죠. 위 코드에서 람다식을 메서드 참조 표현식으로 변경해보면 다음과 같습니다.

 

// 일반 람다식
String collect = memberList.stream().map(element -> element.getName()).collect(Collectors.joining());

// 메서드 참조 표현식
String collect = memberList.stream().map(Member::getName).collect(Collectors.joining());

 

위 코드에서 메서드 참조 표현식의 사용 형태는 다음과 같습니다.

 

// 일반 람다식
(인스턴스 -> 인스턴스.메서드명)

// 메서드 참조 표현식
(인스턴스의 클래스명::메서드명)

 

 

인스턴스를 생성하는 경우

public class Main {
    public static void main(String[] args) {
        List<String> memberNameList = List.of("A", "B", "C");
        List<Member> memberList = memberNameList.stream().map(name -> new Member(name)).collect(Collectors.toList());
        memberList.forEach(member -> System.out.println(member.getName()));
    }

    public static class Member {
        private String name;

        public Member(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }
}

 

위 코드에서 memberList를  초기화할 때 stream 생성 이후 map 메서드에서 람다식을 사용했습니다. 이때 map에 걸리는 요소들은 String 객체지만, Member 클래스의 인스턴스를 만들 때 인자로 들어갑니다. 이때도 메서드 참조 표현식이 가능합니다. 위 코드에서 람다식을 메서드 참조 표현식으로 변경해보면 다음과 같습니다.

 

// 일반 람다식
List<Member> memberList = memberNameList.stream().map(name -> new Member(name)).collect(Collectors.toList());

// 메서드 참조 표현식
List<Member> memberList = memberNameList.stream().map(Member::new).collect(Collectors.toList());

 

위 코드에서 메서드 참조 표현식의 사용 형태는 다음과 같습니다. 특히, 이렇게 메서드가 아닌 생성자를 참조할 때는 생성자 참조 표현식이라고 부릅니다.

 

// 일반 람다식
(인자로 들어갈 객체 -> new 클래스명(인자로 들어갈 객체))

// 메서드 참조 표현식
(클래스명::new)

 

 

 

결론

람다식을 이용할 때 메서드 참조 표현식을 사용하면 간결해질 수 있다는 장점이 있지만, 람다식 혹은 메서드 참조 표현식에 익숙하지 않은 동료와 함께 개발한다면 오히려 가독성을 해칠 수 있다는 우려도 있습니다. 간결한 것도 좋지만 동료와 컨벤션을 맞추어 모두에게 가독성이 좋은 개발하는 것이 최고라고 생각합니다.

 

참고로 위에 보여드린 예시는 정말 일부일 뿐이며, IntelliJ를 사용하신다면 IntelliJ가 메서드 참조 표현식을 사용할 수 있을 때 해당 부분을 하이라이트 처리해준 후 메시지를 띄워줍니다. 그러니 이런 사소한 것까지 외우기보다는 이런 표현 방식도 있구나 정도로 이해해주시면 될 것 같습니다.

반응형
저작자표시 (새창열림)

'Dev > Java' 카테고리의 다른 글

[Java] 배열(Array) vs. 배열리스트(ArrayList) vs. 연결리스트(LinkedList)  (2) 2021.03.30
[Java] gradle 환경에서 JMH를 사용하여 벤치마킹하기  (0) 2021.03.22
[Java] 객체와 클래스, 인스턴스 간 차이  (4) 2021.03.10
    'Dev/Java' 카테고리의 다른 글
    • [Java] 배열(Array) vs. 배열리스트(ArrayList) vs. 연결리스트(LinkedList)
    • [Java] gradle 환경에서 JMH를 사용하여 벤치마킹하기
    • [Java] 객체와 클래스, 인스턴스 간 차이
    몽-구
    몽-구
    소망보단 목표를, 생각보단 실천을

    티스토리툴바