Post

🐹 chap3. λžŒλ‹€ ν‘œν˜„μ‹

3.1 λžŒλ‹€λž€ 무엇인가?

: λ©”μ„œλ“œλ‘œ 전달할 수 μžˆλŠ” 읡λͺ… ν•¨μˆ˜λ₯Ό λ‹¨μˆœν™”ν•œ 것

  • 읡λͺ…

    λ³΄ν†΅μ˜ λ©”μ„œλ“œμ™€ 달리 이름이 μ—†μœΌλ―€λ‘œ 읡λͺ…이라 ν‘œν˜„ν•œλ‹€.

  • ν•¨μˆ˜

    λžŒλ‹€λŠ” λ©”μ„œλ“œμ²˜λŸΌ νŠΉμ • ν΄λž˜μŠ€μ— μ’…μ†λ˜μ§€ μ•ŠμœΌλ―€λ‘œ ν•¨μˆ˜λΌκ³  λΆ€λ₯Έλ‹€. ν•˜μ§€λ§Œ λ©”μ„œλ“œμ²˜λŸΌ νŒŒλΌλ―Έν„° 리슀트, λ°”λ””, λ°˜ν™˜ ν˜•μ‹, κ°€λŠ₯ν•œ μ˜ˆμ™Έ 리슀트λ₯Ό ν¬ν•¨ν•œλ‹€.

  • 전달

    λžŒλ‹€ ν‘œν˜„μ‹μ„ λ©”μ„œλ“œ 인수둜 μ „λ‹¬ν•˜κ±°λ‚˜ λ³€μˆ˜λ‘œ μ €μž₯ν•  수 μžˆλ‹€.

  • κ°„κ²°μ„±

    읡λͺ… 클래슀처럼 λ§Žμ€ μžμ§ˆκ΅¬λ ˆν•œ μ½”λ“œλ₯Ό κ΅¬ν˜„ν•  ν•„μš”κ°€ μ—†λ‹€.

μ˜ˆμ‹œ) μ»€μŠ€ν…€ Comparator 객체λ₯Ό 기쑴보닀 κ°„λ‹¨νžˆ κ΅¬ν˜„ν•˜κΈ°

  • κΈ°μ‘΄ μ½”λ“œ

    1
    2
    3
    4
    5
    
      Comparator<Apple> byWeight = new Comparator<Apple>() {
      		public int compare(Apple a1, Apple a2) {
      				return a1.getWeight().compareTo(a2.getWeight());
      		}
      };
    
  • λžŒλ‹€ μ½”λ“œ

    1
    2
    
      Comparator<Apple> byWeight = 
      		(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
    

[ λžŒλ‹€μ˜ ꡬ쑰 ]

  • νŒŒλΌλ―Έν„° 리슀트

    Comparator의 compare λ©”μ„œλ“œ νŒŒλΌλ―Έν„°(사과 두 개)

  • ν™”μ‚΄ν‘œ

    ν™”μ‚΄ν‘œ(->)λŠ” λžŒλ‹€μ˜ νŒŒλΌλ―Έν„° λ¦¬μŠ€νŠΈμ™€ λ°”λ””λ₯Ό κ΅¬λΆ„ν•œλ‹€.

  • λžŒλ‹€ λ°”λ””

    두 μ‚¬κ³Όμ˜ 무게λ₯Ό λΉ„κ΅ν•œλ‹€. λžŒλ‹€μ˜ λ°˜ν™˜κ°’μ— ν•΄λ‹Ήν•˜λŠ” ν‘œν˜„μ‹μ΄λ‹€.

[ μžλ°” 8의 μœ νš¨ν•œ λžŒλ‹€ ν‘œν˜„μ‹ μ˜ˆμ‹œ ]

  • ν‘œν˜„μ‹ μŠ€νƒ€μΌ

    1
    
      (parameters) -> expression
    
  • 블둝 μŠ€νƒ€μΌ

    1
    
      (parameters) -> { statements; }
    
  • Quiz. λžŒλ‹€ 문법

    λžŒλ‹€ κ·œμΉ™μ— λ§žμ§€ μ•ŠλŠ” λžŒλ‹€ ν‘œν˜„μ‹μ„ κ³ λ₯΄μ‹œμ˜€.

    1. ( ) β†’ { }
    2. ( ) β†’ β€œRaoul”
    3. ( ) β†’ {return β€œMario”;}
    4. (Integer i) β†’ return β€œAlan” + i;
    5. (String s) β†’ {”Iron Man”;}
      • μ •λ‹΅

      4번과 5번이 μœ νš¨ν•˜μ§€ μ•Šμ€ λžŒλ‹€ ν‘œν˜„μ‹μ΄λ‹€.

      1. νŒŒλΌλ―Έν„°κ°€ μ—†μœΌλ©° voidλ₯Ό λ°˜ν™˜ν•˜λŠ” λžŒλ‹€ ν‘œν˜„μ‹μ΄λ‹€. μ΄λŠ” public void run() {} 처럼 λ°”λ””κ°€ μ—†λŠ” λ©”μ„œλ“œμ™€ κ°™λ‹€.
      2. νŒŒλΌλ―Έν„°κ°€ μ—†μœΌλ©° λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•˜λŠ” ν‘œν˜„μ‹μ΄λ‹€.
      3. νŒŒλΌλ―Έν„°κ°€ μ—†μœΌλ©° (λͺ…μ‹œμ μœΌλ‘œ return 문을 μ΄μš©ν•΄μ„œ) λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•˜λŠ” ν‘œν˜„μ‹μ΄λ‹€.
      4. return은 흐름 μ œμ–΄λ¬Έμ΄λ‹€. (Integer i) β†’ {return β€œAlan” + i;}처럼 λ˜μ–΄μ•Ό μ˜¬λ°”λ₯Έ λžŒλ‹€ ν‘œν˜„μ‹μ΄λ‹€.
      5. β€œIron Man”은 ꡬ문(statement)이 μ•„λ‹ˆλΌ ν‘œν˜„μ‹(expression)이닀. (String s) -> {return β€œIron Man”;}처럼 λͺ…μ‹œμ μœΌλ‘œ return 문을 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

[ λžŒλ‹€ μ˜ˆμ œμ™€ μ‚¬μš© 사둀 ]

3.2 어디에, μ–΄λ–»κ²Œ λžŒλ‹€λ₯Ό μ‚¬μš©ν• κΉŒ?

Comparator ν˜•μ‹ λ³€μˆ˜μ— λžŒλ‹€ ν• λ‹Ή

1
2
List<Apple> greenApples =
		filter(inventory, **(Apple a) -> GREEN.equals(a.getColor())**);

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ—μ„œ λžŒλ‹€ν˜• ν‘œν˜„μ‹μ„ μ‚¬μš©ν•  수 μžˆλ‹€.

3.2.1 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

Predicate μΈν„°νŽ˜μ΄μŠ€λ‘œ ν•„ν„° λ©”μ„œλ“œλ₯Ό νŒŒλΌλ―Έν„°ν™” ν–ˆμ—ˆλŠ”λ°, 이것이 λ°”λ‘œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€.

PredicateλŠ” **였직 ν•˜λ‚˜μ˜ 좔상 λ©”μ„œλ“œλ§Œ 지정**ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

1
2
3
public interface Predicate<T> {
		boolean test (T t);
}
ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

μ •ν™•νžˆ ν•˜λ‚˜μ˜ 좔상 λ©”μ„œλ“œλ₯Ό μ§€μ •ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€

Comparator, Runnable 등이 μžˆλ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public interface Comparator<T> { // java.util.Comparator
		int compare(T o1, T o2);
}

public interface Runnable { // java.lang.Runnable
		void run();
}

// java.awt.event.ActionListener
public interface ActionListner extends EventListener { 
		void actionPerformed(ActionEvent e);
}

public interface Callable<V> { // java.util.concurrent.Callable
		V call() throws Exception;
}

public interface PrivilegedAction<T> { // java.security.PrivilegedAction
		T run();
}
  • Quiz. ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

    λ‹€μŒ μΈν„°νŽ˜μ΄μŠ€ 쀑 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λŠ” μ–΄λŠ 것인가?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      public interface Adder {
      		int add(int a, int b);
      }
        
      public interface SmartAdder extends Adder {
      		int add(double a, double b);
      }
        
      public interface Nothing {
      }
    
    • μ •λ‹΅

      Adder만 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€.

      SmartAdderλŠ” 두 좔상 add λ©”μ„œλ“œ(ν•˜λ‚˜λŠ” Adderμ—μ„œ μƒμ†λ°›μŒ)λ₯Ό ν¬ν•¨ν•˜λ―€λ‘œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€κ°€ μ•„λ‹ˆλ‹€.

      Nothing은 좔상 λ©”μ„œλ“œκ°€ μ—†μœΌλ―€λ‘œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€κ°€ μ•„λ‹ˆλ‹€.

λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ˜ 좔상 λ©”μ„œλ“œ κ΅¬ν˜„μ„ 직접 전달할 수 μžˆμœΌλ―€λ‘œ 전체 ν‘œν˜„μ‹μ„ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ˜ μΈμŠ€ν„΄μŠ€λ‘œ μ·¨κΈ‰ν•  수 μžˆλ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// λžŒλ‹€ μ‚¬μš©
Runnable r1 = () -> System.out.println("Hello World 1");

// 읡λͺ… 클래슀 μ‚¬μš©
Runnable r2 = new Runnable() {
		public void run() {
				System.out.println("Hello World 2");
		}
};

public static void process(Runnable r) {
		r.run();
}
process(r1); // 'Hello World 1' 좜λ ₯
process(r2); // 'Hello World 2' 좜λ ₯
// 직접 μ „λ‹¬λœ λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ 'Hello World 3' 좜λ ₯
process(() -> System.out.println("Hello World 3")); 

Runnable은 였직 ν•˜λ‚˜μ˜ 좔상 λ©”μ„œλ“œ run을 μ •μ˜ν•˜λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ΄λ―€λ‘œ μ˜¬λ°”λ₯Έ μ½”λ“œλ‹€.

3.2.2 ν•¨μˆ˜ λ””μŠ€ν¬λ¦½ν„°

: λžŒλ‹€ ν‘œν˜„μ‹μ˜ μ‹œκ·Έλ‹ˆμ²˜(ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ˜ 좔상 λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜)λ₯Ό μ„œμˆ ν•˜λŠ” λ©”μ„œλ“œ

ex) Runnable μΈν„°νŽ˜μ΄μŠ€μ˜ μœ μΌν•œ 좔상 λ©”μ„œλ“œ run은 μΈμˆ˜μ™€ λ°˜ν™˜κ°’μ΄ μ—†μœΌλ―€λ‘œ(void λ°˜ν™˜) Runnable μΈν„°νŽ˜μ΄μŠ€λŠ” μΈμˆ˜μ™€ λ°˜ν™˜κ°’μ΄ μ—†λŠ” μ‹œκ·Έλ‹ˆμ²˜λΌκ³  생각할 수 μžˆλ‹€.

1
2
3
4
5
public void process(Runnable r) {
		r.run();
}

process(() -> System.out.println("This is awesome!!"));

μœ„ μ½”λ“œμ—μ„œ () -> Systeml.out.println("This is awesome!!")은 μΈμˆ˜κ°€ μ—†μœΌλ©° voidλ₯Ό λ°˜ν™˜ν•˜λŠ” λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ Runnable μΈν„°νŽ˜μ΄μŠ€μ˜ run λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜μ™€ κ°™λ‹€.

μ΄λ•Œ ν•œ 개의 void λ©”μ„œλ“œ ν˜ΈμΆœμ€ μ€‘κ΄„ν˜Έλ‘œ κ°μŒ€ ν•„μš”κ°€ μ—†λ‹€.

  • Quiz. 어디에 λžŒλ‹€λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ”κ°€?

    λ‹€μŒ 쀑 λžŒλ‹€ ν‘œν˜„μ‹μ„ μ˜¬λ°”λ₯΄κ²Œ μ‚¬μš©ν•œ μ½”λ“œλŠ”?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
      // 1번 μ½”λ“œ
      execute((() -> {});
      public void execute(Runnable r) {
      		r.run();
      }
        
      // 2번 μ½”λ“œ
      public Callable<String> fetch() {
      		return () -> "Tricky examplel ;-)";
      }
        
      // 3번 μ½”λ“œ
      Predicate<Apple> p = (Apple a) -> a.getWeight();
    
    • μ •λ‹΅

      1번과 2λ²ˆμ€ μœ νš¨ν•œ λžŒλ‹€ ν‘œν˜„μ‹μ΄λ‹€.

      첫 번째 μ˜ˆμ œμ—μ„œ λžŒλ‹€ ν‘œν˜„μ‹ ( ) -> { }의 μ‹œκ·Έλ‹ˆμ²˜λŠ” ( ) -> void 이며 Runnable의 좔상 λ©”μ„œλ“œ run의 μ‹œκ·Έλ‹ˆμ²˜μ™€ μΌμΉ˜ν•˜λ―€λ‘œ μœ νš¨ν•œ λžŒλ‹€ ν‘œν˜„μ‹μ΄λ‹€. λ‹€λ§Œ λžŒλ‹€μ˜ λ°”λ””κ°€ λΉ„μ–΄μžˆμœΌλ―€λ‘œ 이 μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ 아무 일도 μΌμ–΄λ‚˜μ§€ μ•ŠλŠ”λ‹€.

      두 번째 μ˜ˆμ œλ„ μœ νš¨ν•œ λžŒλ‹€ ν‘œν˜„μ‹μ΄λ‹€. fetch λ©”μ„œλ“œμ˜ λ°˜ν™˜ ν˜•μ‹μ€ Callable이닀. Tλ₯Ό String으둜 λŒ€μΉ˜ν–ˆμ„ λ•Œ Callable λ©”μ„œλ“œμ˜ μ‹œκ·Έλ‹ˆμ²˜λŠ” ( ) -> String이 λœλ‹€. ( ) -> β€œTricky example ;-)β€λŠ” ( ) -> String μ‹œκ·Έλ‹ˆμ²˜μ΄λ―€λ‘œ λ¬Έλ§₯상 μœ νš¨ν•œ λžŒλ‹€ ν‘œν˜„μ‹μ΄λ‹€.

      μ„Έ 번째 μ˜ˆμ œμ—μ„œ λžŒλ‹€ ν‘œν˜„μ‹ (Apple a) -> a.getWeight()의 μ‹œκ·Έλ‹ˆμ²˜λŠ” (Apple) -> Integer μ΄λ―€λ‘œ Predicate : (Apple) -> boolean의 test λ©”μ„œλ“œμ˜ μ‹œκ·Έλ‹ˆμ²˜μ™€ μΌμΉ˜ν•˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ μœ νš¨ν•œ λžŒλ‹€ ν‘œν˜„μ‹μ΄ μ•„λ‹ˆλ‹€.

3.3 λžŒλ‹€ ν™œμš© : μ‹€ν–‰ μ–΄λΌμš΄λ“œ νŒ¨ν„΄

λžŒλ‹€μ™€ λ™μž‘ νŒŒλΌλ―Έν„°ν™”λ‘œ μœ μ—°ν•˜κ³  κ°„κ²°ν•œ μ½”λ“œλ₯Ό κ΅¬ν˜„ν•˜λŠ” 데 도움이 λ˜λŠ” μ˜ˆμ œμ—λŠ” μžμ›μ²˜λ¦¬(ex. λ°μ΄ν„°λ² μ΄μŠ€μ˜ 파일 처리)κ°€ μžˆλ‹€.

μˆœν™˜ νŒ¨ν„΄μœΌλ‘œ μžμ›μ„ μ—΄κ³ , μ²˜λ¦¬ν•œ λ‹€μŒμ—, μžμ›μ„ λ‹«λŠ” μˆœμ„œλ‘œ 이루어진닀.

[ μ‹€ν–‰ μ–΄λΌμš΄λ“œ νŒ¨ν„΄ ]

1
2
3
4
5
6
public String processFile() throws IOException {
		**try (BufferedReader br =
						new BufferedReader(new FileReader("data.txt")))** {
				return br.readLine(); // μ‹€μ œ ν•„μš”ν•œ μž‘μ—…μ„ ν•˜λŠ” 행이닀.
		}
}

ꡡ은 κΈ€μ”¨λŠ” νŒŒμΌμ—μ„œ ν•œ 행을 μ½λŠ” μ½”λ“œλ‹€.

3.3.1 1단계 : λ™μž‘ νŒŒλΌλ―Έν„°ν™”λ₯Ό κΈ°μ–΅ν•˜λΌ

μœ„μ˜ μ½”λ“œλŠ” νŒŒμΌμ—μ„œ ν•œ λ²ˆμ— ν•œ μ€„λ§Œ 읽을 수 μžˆλ‹€. μž‘μ—…μ„ λ³€κ²½ν•˜λ €λ©΄ 기쑴의 μ„€μ •, 정리 과정은 μž¬μ‚¬μš©ν•˜κ³  processFile λ©”μ„œλ“œλ§Œ λ‹€λ₯Έ λ™μž‘μ„ μˆ˜ν–‰ν•˜λ„λ‘ ν•˜λŠ” 것이 쒋을 것이닀.

즉, processFile의 λ™μž‘μ„ νŒŒλΌλ―Έν„°ν™”ν•˜λŠ” 것이닀.

λžŒλ‹€λ₯Ό μ΄μš©ν•΄ λ™μž‘μ„ μ „λ‹¬ν•œλ‹€. λ‹€μŒμ€ BufferedReaderμ—μ„œ 두 행을 좜λ ₯ν•˜λŠ” μ½”λ“œλ‹€.

1
2
String result = processFile((BufferedReader br) ->
															br.readLine() + br.readLine());

3.3.2 2단계 : ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•΄μ„œ λ™μž‘ 전달

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ μžλ¦¬μ— λžŒλ‹€λ₯Ό μ‚¬μš©ν•  수 μžˆμœΌλ―€λ‘œ, BufferedReader -> Stringκ³Ό IOException을 던질 수 μžˆλŠ” μ‹œκ·Έλ‹ˆμ²˜μ™€ μΌμΉ˜ν•˜λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“€μ–΄μ•Ό ν•œλ‹€. 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό BufferedReaderProcessor 라고 μ •μ˜ν•˜μž.

1
2
3
4
@FunctionalInterface
public interface BufferedReaderProcessor {
		String process(BufferedReader b) throws IOException;
}

μ •μ˜ν•œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό processFile λ©”μ„œλ“œμ˜ 인수둜 전달할 수 μžˆλ‹€.

1
2
3
public String processFile(BufferedReaderProcessor p) throws IOException {
		...
}

3.3.3 3단계 : λ™μž‘ μ‹€ν–‰

이제 BufferedReaderProcessor에 μ •μ˜λœ process λ©”μ„œλ“œμ˜ μ‹œκ·Έλ‹ˆμ²˜(BufferedReader -> String)κ³Ό μΌμΉ˜ν•˜λŠ” λžŒλ‹€λ₯Ό 전달할 수 μžˆλ‹€.

processFile λ°”λ”” λ‚΄μ—μ„œ BufferedReaderProcessor 객체의 processλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.

1
2
3
4
5
public String processFile(BufferedReaderProcessor p) throws IOException {
		try (BufferedReader br =
								new BufferReader(new FileReader("data.txt"))) {
				return p.process(br); // BufferedReader 객체 처리
}

3.3.4 4단계 : λžŒλ‹€ 전달

이제 λžŒλ‹€λ₯Ό μ΄μš©ν•΄ λ‹€μ–‘ν•œ λ™μž‘μ„ processFile λ©”μ„œλ“œλ‘œ 전달할 수 μžˆλ‹€.

λ‹€μŒμ€ ν•œ 행을 μ²˜λ¦¬ν•˜λŠ” μ½”λ“œλ‹€.

1
String oneLine = processFile((BufferedReader br) -> br.readLine());

λ‹€μŒμ€ 두 행을 μ²˜λ¦¬ν•˜λŠ” μ½”λ“œλ‹€.

1
String twoLines = processFile((BufferedReader br) -> br.readLine() + br.readLine());

[ processFile λ©”μ„œλ“œλ₯Ό 더 μœ μ—°ν•˜κ²Œ λ§Œλ“œλŠ” κ³Όμ • ]

3.4 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ μ‚¬μš©

ν•¨μˆ˜ λ””μŠ€ν¬λ¦½ν„°

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ˜ 좔상 λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜

3.4.2 Consumer

java.util.function.Consumer μΈν„°νŽ˜μ΄μŠ€λŠ” **μ œλ„€λ¦­ ν˜•μ‹ T 객체λ₯Ό λ°›μ•„μ„œ voidλ₯Ό λ°˜ν™˜**ν•˜λŠ” acceptλΌλŠ” 좔상 λ©”μ„œλ“œλ₯Ό μ •μ˜ν•œλ‹€. T ν˜•μ‹μ˜ 객체λ₯Ό 인수둜 λ°›μ•„ μ–΄λ–€ λ™μž‘μ„ μˆ˜ν–‰ν•˜κ³  싢을 λ•Œ Consumer μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

λ‹€μŒμ€ forEach와 λžŒλ‹€λ₯Ό μ΄μš©ν•΄μ„œ 리슀트의 λͺ¨λ“  ν•­λͺ©μ„ 좜λ ₯ν•˜λŠ” μ˜ˆμ œλ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@FunctionalInterface
public interface Consumer<T> {
		void accept(T t);
}

public <T> void forEach(List<T> list, Consumer<T> c) {
		for(T t: list) {
				c.accept(t);
		}
}
forEach(
				Arrays.asList(1,2,3,4,5),
				// Consumer의 accept λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜λŠ” λžŒλ‹€
				(Integer i) -> System.out.println(i) 
);

3.4.3 Function

java.util.function.Function<T, R> μΈν„°νŽ˜μ΄μŠ€λŠ” μ œλ„€λ¦­ ν˜•μ‹ Tλ₯Ό 인수둜 λ°›μ•„μ„œ μ œλ„€λ¦­ ν˜•μ‹ R 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 좔상 λ©”μ„œλ“œ applyλ₯Ό μ •μ˜ν•œλ‹€. μž…λ ₯을 좜λ ₯으둜 λ§€ν•‘ν•˜λŠ” λžŒλ‹€λ₯Ό μ •μ˜ν•  λ•Œ Function μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν™œμš©ν•  수 μžˆλ‹€.(ex. μ‚¬κ³Όμ˜ 무게 정보λ₯Ό μΆ”μΆœν•˜κ±°λ‚˜ λ¬Έμžμ—΄μ„ 길이와 맀핑)

λ‹€μŒμ€ String 리슀트λ₯Ό 인수둜 λ°›μ•„ 각 String의 길이λ₯Ό ν¬ν•¨ν•˜λŠ” Integer 리슀트둜 λ³€ν™˜ν•˜λŠ” map λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜λŠ” μ˜ˆμ œλ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@FunctionalInterface
public interface Function<T, R> {
		R apply(T t);
}

public <T, R> List<R> map(List<T> list, Function<T, R> f) {
		List<R> result = new ArrayList<>();
		for(T t:list) {
				result.add(f.apply(t));
		}
		return result;
}

// [7, 2, 6]
List<Integer> l = map(
				Arrays.asList("lambdas", "in", "action"),
				(String s) -> s.length() // Function의 apply λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜λŠ” λžŒλ‹€
);

κΈ°λ³Έν˜• νŠΉν™”

μ§€κΈˆκΉŒμ§€ λ³Έ μ„Έ 개의 μ œλ„€λ¦­ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ Predicate, Consumer, Function<T, R>을 μ‚΄νŽ΄λ΄€λ‹€. 이외에도 νŠΉν™”λœ ν˜•μ‹μ˜ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ„ μžˆλ‹€.

μžλ°”λŠ” κΈ°λ³Έν˜•κ³Ό μ°Έμ‘°ν˜• 두 가지가 μžˆλŠ”λ°, μ œλ„€λ¦­ νŒŒλΌλ―Έν„°μ—λŠ” μ°Έμ‘°ν˜•λ§Œ μ‚¬μš©ν•  수 μžˆλ‹€.

  • λ°•μ‹± : κΈ°λ³Έν˜•μ„ μ°Έμ‘°ν˜•μœΌλ‘œ λ³€ν™˜
  • μ–Έλ°•μ‹± : μ°Έμ‘°ν˜•μ„ κΈ°λ³Έν˜•μœΌλ‘œ λ³€ν™˜
  • μ˜€ν† λ°•μ‹± : λ°•μ‹±κ³Ό 언박싱이 μžλ™μœΌλ‘œ 이루어짐

    1
    2
    3
    4
    
      List<Integer> list = new ArrayList<>();
      for (int i = 300; i < 400; i++) {
      		list.add(i);
      }
    

    intκ°€ Integer둜 λ°•μ‹±λ˜μ—ˆλ‹€.

ν•˜μ§€λ§Œ 이런 λ³€ν™˜ 과정은 λΉ„μš©μ΄ μ†Œλͺ¨λœλ‹€. λ°•μ‹±ν•œ 값은 λ©”λͺ¨λ¦¬λ₯Ό 더 μ†ŒλΉ„ν•˜λ©° κΈ°λ³Έν˜•μ„ κ°€μ Έμ˜¬ λ•Œλ„ λ©”λͺ¨λ¦¬λ₯Ό νƒμƒ‰ν•˜λŠ” 과정이 ν•„μš”ν•˜λ‹€.

μžλ°” 8μ—μ„œλŠ” μ˜€ν† λ°•μ‹± λ™μž‘μ„ ν”Όν•  수 μžˆλ„λ‘ νŠΉλ³„ν•œ λ²„μ „μ˜ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•œλ‹€.

λ‹€μŒ μ˜ˆμ œμ—μ„œ IntPredicateλŠ” 1000μ΄λΌλŠ” 값을 λ°•μ‹±ν•˜μ§€ μ•Šμ§€λ§Œ, PredicateλŠ” 1000μ΄λΌλŠ” 값을 Integer 객체둜 λ°•μ‹±ν•œλ‹€.

1
2
3
4
5
6
7
8
9
public interface IntPredicate {
		boolean test(int t);
}

IntPredicate evenNumbers = (int i) -> i % 2 == 0;
evenNumber.test(1000); // μ°Έ(λ°•μ‹± μ—†μŒ)

Predicate<Integer> oddNumbers = (Integer i) -> i % 2 != 0;
oddNumbers.test(1000); // 거짓(λ°•μ‹±)

μ΄λ ‡κ²Œ νŠΉμ • ν˜•μ‹μ„ μž…λ ₯으둜 λ°›λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ 이름 μ•žμ— ν˜•μ‹λͺ…이 λΆ™λŠ”λ‹€.

ex.) IntConsumer, LongBinaryOperator, IntFunction

Function μΈν„°νŽ˜μ΄μŠ€ β†’ ToIntFunction, IntToDoubleFunction λ“± λ‹€μ–‘ν•œ 좜λ ₯ ν˜•μ‹ νŒŒλΌλ―Έν„° 제곡

This post is licensed under CC BY 4.0 by the author.