πΉ 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. λλ€ λ¬Έλ²
λλ€ κ·μΉμ λ§μ§ μλ λλ€ ννμμ κ³ λ₯΄μμ€.
- ( ) β { }
- ( ) β βRaoulβ
- ( ) β {return βMarioβ;}
- (Integer i) β return βAlanβ + i;
- (String s) β {βIron Manβ;}
- μ λ΅
4λ²κ³Ό 5λ²μ΄ μ ν¨νμ§ μμ λλ€ ννμμ΄λ€.
- νλΌλ―Έν°κ° μμΌλ©° voidλ₯Ό λ°ννλ λλ€ ννμμ΄λ€. μ΄λ public void run() {} μ²λΌ λ°λκ° μλ λ©μλμ κ°λ€.
- νλΌλ―Έν°κ° μμΌλ©° λ¬Έμμ΄μ λ°ννλ ννμμ΄λ€.
- νλΌλ―Έν°κ° μμΌλ©° (λͺ μμ μΌλ‘ return λ¬Έμ μ΄μ©ν΄μ) λ¬Έμμ΄μ λ°ννλ ννμμ΄λ€.
- returnμ νλ¦ μ μ΄λ¬Έμ΄λ€. (Integer i) β {return βAlanβ + i;}μ²λΌ λμ΄μΌ μ¬λ°λ₯Έ λλ€ ννμμ΄λ€.
- β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
λ€μμ 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
μλ°λ κΈ°λ³Ένκ³Ό μ°Έμ‘°ν λ κ°μ§κ° μλλ°, μ λ€λ¦ νλΌλ―Έν°μλ μ°Έμ‘°νλ§ μ¬μ©ν μ μλ€.
- λ°μ± : κΈ°λ³Ένμ μ°Έμ‘°νμΌλ‘ λ³ν
- μΈλ°μ± : μ°Έμ‘°νμ κΈ°λ³ΈνμΌλ‘ λ³ν
μ€ν λ°μ± : λ°μ±κ³Ό μΈλ°μ±μ΄ μλμΌλ‘ μ΄λ£¨μ΄μ§
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
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