본문 바로가기

# 02/Java

[윤성우 열혈자바] 28-1. 메소드 참조

반응형

메소드 참조의 4가지 유형과 메소드 참조의 장점


● static 메소드의 참조


● 참조 변수를 통한 인스턴스 메소드 참조


● 클래스 이름을 통한 인스턴스 메소드 참조


● 생성자 참조


기본적으로 람다식보다 조금 더 코드를 단순하게 할 수 있다는 장점이 있다.

일부 람다식을 메소드 참조로 대신하게 할 수 있다.








static 메소드의 참조 : 람다식 기반 예제


Consumer<T> void accept(T t)


Collections 클래스의 reverse 메소드 기반 예제

public static void reverse(List<?> list)            // 저장 순서를 뒤집는다.


class ArrangeList {

public static void main(String[] args) {

List<Integer> ls = Arrays.asList(1, 3, 5, 7, 9);

ls = new ArrayList<>(ls);


Consumer<List<Integer>> c = l -> Collections.reverse(l);            // reverse 메소드 호출 중심의 람다식

c.accept(ls);            // 순서 뒤집기 진행

System.out.println(ls);                // 출력

}

}









static 메소드의 참조 : 메소드 참조 기반으로 수정


Consumer<T>    void accept(T t)


Consumer<List<Integer>> c = l -> Collections.reverse(l);

   → Consumer<List<Integer>> c = Collections::reverse;



accept 메소드 호출  전달되는 인자를 reverse 메소드를 호출하면서 그대로 전달한다는 약속에 근거한 수정



void accept(T t)

void reverse(List<?> list)


accept 전달된  reverse 그대로. . .








인스턴스 메소드 참조 1 : effectively final


Consumer<T>    void accept(T t)


class JustSort {

   public void sort(List<?> lst) { // 인스턴스 메소드

      Collections.reverse(lst);

   }

}

 

class ArrangeList3 {

   public static void main(String[] args) {

      List<Integer> ls = Arrays.asList(1, 3, 5, 7, 9);

      ls = new ArrayList<>(ls);

      JustSort js = new JustSort();   // js effectively final (사실상 상수) - js가 참조하는 인스턴스는 바뀌지 않음!

     

      Consumer<List<Integer>> c = e -> js.sort(e); // 람다식 기반

      c.accept(ls);

      System.out.println(ls);

   }

}


[9, 7, 5, 3, 1]








인스턴스 메소드 참조 1 : 인스턴스 존재 상황에서 참조


Consumer<T>    void accept(T t)


class JustSort {

   public void sort(List<?> lst) { // 인스턴스 메소드

      Collections.reverse(lst);

   }

}

 

class ArrangeList3 {

   public static void main(String[] args) {

      List<Integer> ls = Arrays.asList(1, 3, 5, 7, 9);

      ls = new ArrayList<>(ls);

      JustSort js = new JustSort();   // js effective final - js 새로운 인스턴스 참조하면 컴파일 오류 뜸!!

     

      Consumer<List<Integer>> c = e -> js.sort(e); // 람다식 기반

           → Consumer<List<Integer>> c = js::sort;

      . . .

   }

}



void accept(T t)

void sort(List<?> list)

accept 전달된  sort 그대로. . .


[9, 7, 5, 3, 1]








인스턴스 메소드 참조 1 : forEach 메소드


Consumer<T>    void accept(T t)


class ForEachDemo {

   public static void main(String[] args) {

      List<String> ls = Arrays.asList("Box", "Robot");

      ls.forEach(s -> System.out.println(s));            // 람다식 기반

      ls.forEach(System.out::println);                // 메소드 참조 기반

   }

}

Consumer<? super T> action = System.out::println


accept 전달된  그대로 println으로. . .



default void forEach(Consumer<? super T> action) {    // Iterable<T> 디폴트 메소드

   for (T t : this)                        // this  메소드가 속한 컬렉션 인스턴스를 의미함

      action.accept(t);            // 모든 저장된 데이터들에 대해  문장 반복

}


Box

Robot

Box

Robot








인스턴스 메소드 참조 2 : 인스턴스 없이 인스턴스 메소드 참조


ToIntBiFunction<T,U>  int applyAsInt(T t, U u)


class IBox {

   private int n;

   public IBox(int i) { n = i; }

   public int larger(IBox b) {

      if(n > b.n)

         return n;

      else

         return b.n;

   }

}



public static void main(String[] args) {

   IBox ib1 = new IBox(5);

   IBox ib2 = new IBox(7);

 

   //  상자에 저장된  비교하여    반환

   ToIntBiFunction<IBox, IBox> bf = (b1, b2) -> b1.larger(b2);

   int bigNum = bf.applyAsInt(ib1, ib2);

   System.out.println(bigNum);

}

// ToIntBiFunction<T, U>     int applyAsInt(T t, U u)


ToIntBiFunction<IBox, IBox> bf = IBox::larger;

약속에 근거한 줄인 표현








생성자 참조


람다식을 작성  인스턴스 생성  이의 참조 값을 반환하는 경우 있다.

 경우 메소드 참조 방식을   있음.


class StringMaker {

   public static void main(String[] args) {

      Function<char[], String> f = ar -> {

         return new String(ar);

      };

      char[] src = {'R', 'o', 'b', 'o', 't'};

      String str = f.apply(src);

      System.out.println(str);

   }

}

// Function<T, R>    R apply(T t)




Function<char[], String> f = ar -> {

         return new String(ar);

      };

->


Function<char[], String> f = ar -> new String(ar);


->


Function<char[], String> f = String::new;




반응형