μ΅λͺ ν΄λμ€ β λλ€ ννμ β λ©μλ μ°Έμ‘°
- λλ€κ° κΈ°μ μ μΌλ‘ μλ° 8 μ΄μ μ λ°λ‘ ν μ μμλ μΌμ μ 곡νλ κ²μ μλλ€.
- λ€λ§ λμ νλΌλ―Έν°λ₯Ό μ΄μ©ν λ μ΅λͺ ν΄λμ€ λ± νμ λ°ν μ½λλ₯Ό ꡬνν νμκ° μλ€.
- λλ€ ννμμ κ΄λ²μνκ² μ¬μ©λλ―λ‘ μ΄ μ₯μ λ΄μ©μ μλ²½νκ² μ΄ν΄ν΄μΌ νλ€.
λλ€μ λͺ©νλ μ ν΄μ§ λμμ λ€λ₯Έ λ©μλμμ μ¬μ©ν μ μλλ‘ νλμ μ‘°κ°μΌλ‘ μΊ‘μν νλ κ²μ΄λ€.
μΈλΆ ꡬνμ ν¬ν¨νλ λλ€ ννμμ 곡κ°νμ§ λ§μμΌ νλ€.
- ννμ μ€νμΌ
(parameters) -> expression
return
μ λͺ μνμ§ μλλ€.
- λΈλ‘ μ€νμΌ
(parameters) -> { statements; }
- λͺ
μμ μΌλ‘
return
λ¬Έμ μ¬μ©ν΄μΌ νλ€.
- λλ€ ννμμ λ©μλλ‘ μ λ¬ν μ μλ μ΅λͺ ν¨μλ₯Ό λ¨μνν κ²μ΄λΌκ³ ν μ μλ€.
- λλ€μ νΉμ§
- μ΅λͺ
- 보ν΅μ λ©μλμ λ¬λ¦¬ μ΄λ¦μ΄ μμΌλ―λ‘ μ΅λͺ μ΄λΌ νννλ€.
- ν¨μ
- λλ€λ λ©μλμ²λΌ νΉμ ν΄λμ€μ μ’ μλμ§ μμΌλ―λ‘ ν¨μλΌκ³ λΆλ₯Έλ€.
- νμ§λ§ λ©μλ μ²λΌ νλΌλ―Έν° 리μ€νΈ , λ°λ , λ°ν νμ , λ°μν μ μλ μμΈ λ¦¬μ€νΈλ κ°μ§ μ μλ€.
- μ λ¬
- λλ€ ννμμ λ©μλ μΈμλ‘ μ λ¬νκ±°λ λ³μλ‘ μ μ₯ν μ μλ€.
- κ°κ²°μ±
- μ΅λͺ ν΄λμ€μ²λΌ λ§μ μμ§κ΅¬λ ν μ½λλ₯Ό ꡬνν νμκ° μλ€.
- μ΅λͺ
Comparator
λ₯Ό ꡬννλ κΈ°μ‘΄ μ½λ
Comparator<Apple> byWeight = new Comparator<Apple>(){
public int compare(Apple a1 , Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
};
λλ€
λ₯Ό μ¬μ©ν μ½λ
Comparator<Apple> byWeight = (Apple a1 , Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
- λλ€ νλΌλ―Έν°
Comparator
μcompare
λ©μλ νλΌλ―Έν°
- νμ΄ν
- λλ€μ νλΌλ―Έν° 리μ€νΈμ λ°λλ₯Ό ꡬλΆνλ€.
- λλ€ λ°λ
- λ μ¬κ³Ό 무κ²λ₯Ό λΉκ΅νλ€. λλ€μ λ°νκ°μ ν΄λΉνλ ννμμ΄λ€.
(String s) -> s.length
String
νμμ νλΌλ―Έν° νλλ₯Ό κ°μ§λ©°int
λ₯Ό λ°ννλ€.- λλ€ ννμμλ returnμ΄ ν¨μΆλμ΄ μμΌλ―λ‘ return λ¬Έμ λͺ μμ μΌλ‘ μ¬μ©νμ§ μμλ λλ€.
(Apple a) -> a.getWeight() > 150
Apple
νμμ νλΌλ―Έν° νλλ₯Ό κ°μ§λ©°boolean
μ λ°ννλ€.
(int x , int y) -> {
System.out.println("Result : " + x + y);
}
int
νμμ νλΌλ―Έν° λ κ°λ₯Ό κ°μ§λ©°void
리ν΄μ΄λ€.- λλ€ ννμμ μ¬λ¬ νμ λ¬Έμ₯μ ν¬ν¨ν μ μλ€.
() -> 42
- νλΌλ―Έν°κ° μμΌλ©°
int
42λ₯Ό λ°ννλ€.
- ν¨μν μΈν°νμ΄μ€λΌλ λ¬Έλ§₯μμ λλ€ ννμμ μ¬μ©ν μ μλ€.
- μ νν νλμ μΆμ λ©μλλ₯Ό μ§μ νλ μΈν°νμ΄μ€
- π ν¨μν μΈν°νμ΄μ€λ‘ λ ν μ μμκΉ?
- λλ€ ννμμΌλ‘ ν¨μν μΈν°νμ΄μ€μ μΆμ λ©μλ ꡬνμ μ§μ μ λ¬ν μ μμΌλ―λ‘ μ 체 ννμμ ν¨μν μΈν°νμ΄μ€μ μΈμ€ν΄μ€λ‘ μ·¨κΈν μ μλ€.
- κΈ°μ μ μΌλ‘ λ°μ§λ©΄ ν¨μν μΈν°νμ΄μ€λ₯Ό ꡬνν ν΄λμ€μ μΈμ€ν΄μ€
// java.util.Comparator
public interface Comparator<T>{
int compare(T o1 , T o2);
}
// java.lang.Runnable
public interface Runnable{
void run();
}
// java.awt.event.ActionListener
public interface ActionListener extends EventListener{
void actionPerformed(ActionEvent e);
}
// java.util.concurrent.Callable
public interface Callable<V>{
V call() thorws Exception;
}
// java.security.PrivilegedAction
public interface PrivilegedAction<T>{
T run();
}
μΈν°νμ΄μ€λ λν΄νΈ λ©μλ (μΈν°νμ΄μ€μ λ©μλλ₯Ό ꡬννμ§ μμ ν΄λμ€λ₯Ό κ³ λ €ν΄μ κΈ°λ³Έ ꡬνμ μ 곡νλ λ°λλ₯Ό ν¬ν¨νλ λ©μλ) λ₯Ό ν¬ν¨ν μ μλ€.
π λ§μ λν΄νΈ λ©μλκ° μλλΌλ μΆμ λ©μλκ° μ€μ§ νλ μ΄λ©΄ ν¨μν μΈν°νμ΄μ€λ€.
μμ μΈν°νμ΄μ€κ° ν¨μν μΈν°νμ΄μ€μΈ λΆλͺ¨ μΈν°νμ΄μ€λ₯Ό νμ₯νκ² λλ©΄ μμ μΈν°νμ΄μ€λ ν¨μν μΈν°νμ΄μ€κ° μλλ€.
Runnable
μ΄ μ€μ§ νλμ μΆμ λ©μλrun
μ μ μνλ ν¨μν μΈν°νμ΄μ€ μ΄λ―λ‘ μλ μμ λ μ¬λ°λ₯Έ ꡬν μ½λμ΄λ€.
class Main {
public static void main(String[] args) throws IOException {
// λλ€ μ¬μ©
Runnable r1 = () -> System.out.println("Hello World");
// μ΅λͺ
ν΄λμ€ μ¬μ©
Runnable r2 = new Runnable(){
public void run(){
System.out.println("Hello World 2");
}
};
process(r1);
process(r2);
// μ§μ μ λ¬λ λλ€ ννμ
process(() -> System.out.println("Hello World 3"));
// Hello World
// Hello World 2
// Hello World 3
}
public static void process(Runnable r){
r.run();
}
}
μ ν¨μν μΈν°νμ΄μ€λ₯Ό μΈμλ‘ λ°λ λ©μλμλ§ λλ€ ννμμ μ¬μ©ν μ μμκΉ?
- μΈμ΄ μ€κ³μλ€μ ν¨μ νμ(λλ€ ννμμ νννλλ° μ¬μ©ν μκ·Έλμ²μ κ°μ νΉλ³ν νκΈ°λ²)μ μΆκ°νλ λ°©λ²λ λμμΌλ‘ κ³ λ €νλ€.
- νμ§λ§ μΈμ΄ μ€κ³μλ€μ μΈμ΄λ₯Ό λ 볡μ‘νκ² λ§λ€μ§ μλ νμ¬ λ°©λ²μ μ ννλ€.
- μ΄λμ λλ€λ₯Ό μ¬μ©ν μ μμκΉ?
1.
execute(() -> {});
public void execute(Runnable r){
r.run();
}
2.
public Callable<String> fetch(){
return () -> "Tricky Example";
}
System.out.println(fetch().call());
3.
Predicate<Apple> p = (Apple a) -> a.getWeight();
- 1λ²κ³Ό 2λ²μ μ ν¨ν λλ€ ννμμ΄λ€.
() -> {}
μ μκ·Έλμ²λ() -> void
λ©°Runnable
μ μΆμ λ©μλrun
μ μκ·Έλμ²μ μΌμΉνλ―λ‘ μ ν¨ν λλ€ ννμμ΄λ€.Callable<String>
μ μκ·Έλμ²λ() -> String
μ΄ λλ€.(Apple a) -> a.getWeight()
λ(Apple) -> Integer
μ΄λ―λ‘Predicate
μ μκ·Έλμ²μ μΌμΉνμ§ μκΈ° λλ¬Έμ μ ν¨νμ§ μλ€.
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
β
@FunctionalInterface
λ 무μμΈκ°?
- ν¨μν μΈν°νμ΄μ€μμ κ°λ¦¬ν€λ μ΄λ Έν μ΄μ μ΄λ€.
@FunctionalInterface
λ‘ μΈν°νμ΄μ€λ₯Ό μ μΈνμ§λ§ μ€μ λ‘ ν¨μν μΈν°νμ΄μ€κ° μλλ©΄ μ»΄νμΌλ¬κ° μλ¬λ₯Ό λ°μμν¨λ€.- μλ₯Όλ€μ΄ , μΆμ λ©μλκ° ν κ° μ΄μμ΄λΌλ©΄ "Multiple nonoverriding abstract methods found int interface Foo"(μΈν°νμ΄μ€ Fooμ μ€λ²λΌμ΄λ νμ§ μμ μ¬λ¬ μΆμ λ©μλκ° μλ€) κ°μ μλ¬κ° λ°μν μ μλ€.
- λλ€μ λμ νλΌλ―Έν°νλ‘ μ μ°νκ³ κ°κ²°ν μ½λλ₯Ό ꡬννλ λ° λμμ μ£Όλ μ€μ©μ μΈ μμ λ₯Ό μ΄ν΄λ³΄μ
- μμ μ²λ¦¬ (μλ₯Ό λ€λ©΄ , λ°μ΄ν° λ² μ΄μ€μ νμΌμ²λ¦¬)μ μ¬μ©νλ μν ν¨ν΄μ μμμ μ΄κ³ , μ²λ¦¬ν λ€μμ , μμμ λ«λ μμλ‘ μ΄λ£¨μ΄μ§λ€.
- μ¦ , μ€μ μμμ μ²λ¦¬νλ μ½λλ₯Ό μ€μ κ³Ό μ 리 λ κ³Όμ μ΄ λλ¬μΈλ ννλ₯Ό μ€ν μ΄λΌμ΄λ ν¨ν΄μ΄λΌκ³ λΆλ₯Έλ€.
public String processFile() throws IOException {
try(BufferedReader br = new BufferedReader(new FileReader("data.txt"))){
return br.readLine();
}
}
- β ν΄λΉ μμ λ μλ° 7μ μλ‘ μΆκ°λ try-with-resourcesλ₯Ό μ¬μ©νλ€.
- νμ¬ μ½λλ νμΌμμ ν λ²μ ν μ€λ§ μ½μ μ μλ€.
- ν λ²μ λ μ€μ μ½κ±°λ κ°μ₯ μμ£Ό μ¬μ©λλ λ¨μ΄λ₯Ό λ°ννλ €λ©΄ μ΄λ»κ² ν΄μΌν κΉ?
- κΈ°μ‘΄μ μ€μ , μ 리 κ³Όμ μ μ¬μ¬μ©νκ³
processFile
λ©μλμ λμμ νλΌλ―Έν°ν ν΄μΌνλ€.
String result = processFile((BufferedReader br) -> br.readLine() + br.readLine());
BufferedReader -> String
κ³ΌIOException
μ λμ§ μ μλ μκ·Έλμ²μ μΌμΉνλ ν¨μν μΈν°νμ΄μ€λ₯Ό λ§λ€μ΄processFile
λ©μλμ μΈμλ‘ μ λ¬ν μ μλ€.
@FunctionalInterface
public interface BufferedReaderProcessor{
String process(BufferedReader br) throws IOException;
}
public String processFile(BufferedReaderProcessor p) throws Exception {
// do something ...
}
process
λ©μλμ μκ·Έλμ²(BufferedReader -> String)
κ³Ό μΌμΉνλ ν¨μν μΈν°νμ΄μ€λ₯Ό λλ€ ννμμΌλ‘ μΆμ λ©μλ ꡬνμ μ§μ μ λ¬ν μ μλ€.- μ λ¬λ μ½λλ ν¨μν μΈν°νμ΄μ€μ μΈμ€ν΄μ€λ‘ μ λ¬λ μ½λμ κ°μ λ°©μμΌλ‘ μ²λ¦¬νλ€.
public String processFile(BufferedReaderProcessr p) throws IOException{
try(BufferedReader br = new BufferedReader(new FileReader("data.txt"))){
return p.process(br);
}
}
- ν¨μν μΈν°νμ΄μ€λ₯Ό λλ€λ‘ μΈμ€ν΄μ€ν ν΄μ λ€μν λμμ
processFile
λ©μλλ‘ μ λ¬ν μ μλ€.
// ν νμ μ²λ¦¬νλ μ½λ
String oneLine = processFile((BufferedReader br) -> br.readLine());
// λ νμ μ²λ¦¬νλ μ½λ
String twoLines = processFile((BufferedReader br) -> br.readLine() + br.readLine());
- ν¨μν μΈν°νμ΄μ€λ μ€μ§ νλμ μΆμ λ©μλλ₯Ό μ§μ νλ€.
- ν¨μν μΈν°νμ΄μ€μ μΆμ λ©μλλ λλ€ ννμμ μκ·Έλμ²λ₯Ό κ°λ¦¬ν€λ©° ν¨μ λμ€ν¬λ¦½ν°λΌκ³ νλ€.
- λ€μν λλ€ ννμμ μ¬μ©νλ €λ©΄ 곡ν΅μ ν¨μ λμ€ν¬λ¦½ν°λ₯Ό κΈ°μ νλ ν¨μν μΈν°νμ΄μ€ μ§ν©μ΄ νμνλ€.
java.util.function
ν¨ν€μ§λ‘ μ¬λ¬κ°μ§ μλ‘μ΄ ν¨μν μΈν°νμ΄μ€λ₯Ό μ 곡νλ€.
- μ λ€λ¦ νμ
T
μ κ°μ²΄λ₯Ό μΈμλ‘ λ°μboolean
μ λ°ννλtest
λΌλ μΆμ λ©μλλ₯Ό μ μνλ€.
public <T> List<T> filter(List<T> list , Predicate<T> p){
List<T> results = new ArrayList<>();
for(T t : list){
if(p.test(t)) results.add(t);
}
return results;
}
Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
List<String> nonEmpty = filter(listOfStrings , nonEmptyStringPredicate);
- μ λ€λ¦ νμ
T
μ κ°μ²΄λ₯Ό μΈμλ‘ λ°μvoid
μ λ°ννλaccept
λΌλ μΆμ λ©μλλ₯Ό μ μνλ€. T
νμμ κ°μ²΄λ₯Ό μΈμλ‘ λ°μμ μ΄λ€ λμμ μννκ³ μΆμ λConsumer
λΌλ μΈν°νμ΄μ€λ₯Ό μ¬μ©ν μ μλ€.
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),
System.out::println // Consumerμ acceptλ©μλλ₯Ό ꡬννλ λλ€
);
- μ λ€λ¦ νμ
T
λ₯Ό μΈμλ‘ λ°μR
κ°μ²΄λ₯Ό λ°ννλapply
λΌλ μΆμ λ©μλλ₯Ό μ μνλ€. - μ
λ ₯μ μΆλ ₯μΌλ‘ 맀ννλ λλ€λ₯Ό μ μν λ
Function
μΈν°νμ΄μ€λ₯Ό νμ©ν μ μλ€.- μ¬κ³Όμ λ¬΄κ² μ 보λ₯Ό μΆμΆνκ±°λ , λ¬Έμμ΄μ κΈΈμ΄μ 맀ν
@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;
}
List<Integer> list = map(
Arrays.asList("lambdas" , "in" , "action"),
(String s) -> s.length()
);
- μλ°μ λͺ¨λ νμμ μ°Έμ‘°ν (Byte , Integer , Object , List...) μλλ©΄ κΈ°λ³Έν (int , double , byte , char...)μ ν΄λΉνλ€.
// int β Integer μ€ν λ°μ±
List<Integer> list = new ArrayList<>();
for(int i = 300 ; i < 400 ; i++){
list.add(i);
}
- ν¨μν μΈν°νμ΄μ€μ μ λ€λ¦ νλΌλ―Έν°μλ μ°Έμ‘°νλ§ μ¬μ©ν μ μκΈ° λλ¬Έμ μμ κ°μ μ€ν λ°μ± λ³ν κ³Όμ μ μννλ λΉμ©μ΄ μλͺ¨λλ€.
- λ°μ±ν κ°μ κΈ°λ³Ένμ κ°μΈλ λνΌλ©° νμ μ μ₯λλ€.
- λ°λΌμ λ°μ±ν κ°μ λ©λͺ¨λ¦¬λ₯Ό λ μλΉνλ©° κΈ°λ³Ένμ κ°μ Έμ¬ λλ λ©λͺ¨λ¦¬λ₯Ό νμνλ κ³Όμ μ΄ νμνλ€.
- π μλ° 8 μμλ κΈ°λ³Ένμ μ μΆλ ₯μΌλ‘ μ¬μ©νλ μν©μμ μ€ν λ°μ± λμμ νΌν μ μλλ‘ νΉλ³ν λ²μ μ ν¨μν μΈν°νμ΄μ€λ₯Ό μ 곡νλ€.
public interface IntPredicate{
boolean test(int t);
}
IntPredicate evenNumbers = (int i) -> i % 2 == 0;
evenNumbers.test(1000);
Predicate<Integer> oddNumbers = (Integer i) -> i % 2 != 0;
oddNumbers.test(1000);
T -> R
Function<T , R>
μ΄ λνμ μΈ μμ λ€.T
νμμ κ°μ²΄λ₯ΌR
νμμ κ°μ²΄λ‘ λ³νν λ μ¬μ©νλ€.
(int , int) -> int
IntBinaryOperator
λ(int , int) -> int
νμμ μκ·Έλμ²λ₯Ό κ°λ μΆμ λ©μλapplyAsInt
λ₯Ό μ μνλ€.
() -> T
Supplier<T>
λ() -> T
νμμ μκ·Έλμ²λ₯Ό κ°λ μΆμ λ©μλget
μ μ μνλ€.Callable<T>
λ() -> T
νμμ μκ·Έλμ²λ₯Ό κ°λ μΆμ λ©μλcall
μ μ μνλ€.
(T , U) -> R
BiFunction<T , U , R>
μ(T , U) -> R
νμμ μκ·Έλμ²λ₯Ό κ°λ μΆμ λ©μλapply
λ₯Ό μ μνλ€.
// booleanνν
// 1. λλ€ μμ
(List<String> list) -> list.isEmpty()
// 2. λμνλ ν¨μν μΈν°νμ΄μ€
Predicate<List<String>>
// κ°μ²΄ μμ±
// 1. λλ€ μμ
() -> new Apple(10)
// 2. λμνλ ν¨μν μΈν°νμ΄μ€
Supplier<Apple>
// κ°μ²΄μμ μλΉ
// 1. λλ€ μμ
(Apple a) -> System.out.println(a.getWeight())
// 2. λμνλ ν¨μν μΈν°νμ΄μ€
Consumer<Apple>
// κ°μ²΄μμ μ ν/μΆμΆ
// 1. λλ€ μμ
(String s) -> s.length()
// 2. λμνλ ν¨μν μΈν°νμ΄μ€
Function<String , Integer> λλ
ToIntFunction<String>
// λ κ° μ‘°ν©
// 1. λλ€ μμ
(int a , int b) -> a * b
// 2. λμνλ ν¨μν μΈν°νμ΄μ€
intBinaryOperator
// λ κ°μ²΄ λΉκ΅
// 1. λλ€ μμ
(Apple a1 , Apple a2) -> a1.getWeight().compareTo(a2.getWeight())
// 2. λμνλ ν¨μν μΈν°νμ΄μ€
Comparator<Apple> λλ
BiFunction<Apple , Apple , Integer> λλ
ToIntBiFunction<Apple , Apple>
// μμΈλ₯Ό λμ§λ λλ€ ννμ
// 1. ν¨μν μΈν°νμ΄μ€μμ μ§μ μ μ
public String processFile(BufferedReaderProcessr p) throws IOException{
try(BufferedReader br = new BufferedReader(new FileReader("data.txt"));){
return p.process(br);
}
}
// 2. try/catch λΈλ‘
Function<BufferedReader , String> f = (BufferedReader b) -> {
try{
return b.readLine();
}
catch(IOException e){
throw new RuntimeException(e);
}
};
- μ»΄νμΌλ¬κ° λλ€μ νμμ μ΄λ»κ² νμΈνλμ§, νΌν΄μΌ ν μ¬νμ 무μμΈμ§ μμ보μ.
- λλ€ ννμ μ체μλ λλ€κ° μ΄λ€ ν¨μν μΈν°νμ΄μ€λ₯Ό ꡬννλμ§μ μ λ³΄κ° ν¬ν¨λμ΄ μμ§ μλ€.
- λλ€μ μ€μ νμμ νμ ν΄λ³΄μ
- λλ€κ° μ¬μ©λλ μ½ν μ€νΈλ₯Ό μ΄μ©ν΄μ λλ€μ νμμ μΆλ‘ ν μ μλ€.
- μ΄λ€ μ½ν μ€νΈ (λλ€κ° μ λ¬λ λ©μλ νλΌλ―Έν°λ λλ€κ° ν λΉλλ λ³μ λ±) μμ κΈ°λλλ λλ€ ννμμ νμμ λμ νμμ΄λΌκ³ λΆλ₯Έλ€.
List<Apple> heavierThan150g = filter(inventory , (Apple apple) -> apple.getWeight() > 150);
- λμ νμ :
Predicate<Apple>
- ν¨μ λμ€ν¬λ¦½ν° :
(Apple) -> Boolean
- λμ νμμ΄λΌλ νΉμ§ λλ¬Έμ κ°μ λλ€ ννμμ΄λλΌλ νΈνλλ μΆμ λ©μλλ₯Ό κ°μ§ λ€λ₯Έ ν¨μλ₯Ό μΈν°νμ΄μ€λ‘ μ¬μ©λ μ μλ€.
- μ¦, νλμ λλ€ ννμμ λ€μν ν¨μν μΈν°νμ΄μ€μ μ¬μ©ν μ μλ€.
Comparator<Apple> c1 = (Apple a1 , Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
ToIntBiFunction<Apple , Apple> c2 = (Apple a1 , Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
BiFunction<Apple , Apple , Integer> c3 = (Apple a1 , Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
κ°μ ν¨μν λμ€ν¬λ¦½ν°λ₯Ό κ°μ§ λ ν¨μν μΈν°νμ΄μ€λ₯Ό κ°λ λ©μλλ₯Ό μ€λ²λΌμ΄λ© ν λ, μ΄λ€ λ©μλμ μκ·Έλμ²κ° μ¬μ©λμ΄μΌ νλμ§λ₯Ό λͺ μμ μΌλ‘ ꡬλΆνλλ‘ λλ€λ₯Ό μΊμ€ν ν μ μλ€.
@FunctionalInterface
interface Action {
void act();
}
public void execute(Runnable runnable) {
runnable.run();
}
public void execute(Action<T> action) {
action.act();
}
execute((Runnable) () -> {});
execute((Action) () -> {});
- μλ° μ»΄νμΌλ¬λ λλ€ ννμμ΄ μ¬μ©λ μ½ν μ€νΈ(λμ νμ)μ μ΄μ©ν΄μ λλ€ ννμκ³Ό κ΄λ ¨λ ν¨μν μΈν°νμ΄μ€λ₯Ό μΆλ‘ νλ€.
- μ¦, λμ νμμ μ΄μ©ν΄μ ν¨μ λμ€ν¬λ¦½ν°λ₯Ό μ μ μμΌλ―λ‘ μ»΄νμΌλ¬λ λλ€μ μκ·Έλμ²λ μΆλ‘ ν μ μλ€.
- κ²°κ³Όμ μΌλ‘ μ»΄νμΌλ¬λ λλ€ ννμμ νλΌλ―Έν° νμμ μ κ·Όν μ μμΌλ―λ‘ λλ€ λ¬Έλ²μμ μ΄λ₯Ό μλ΅ν μ μλ€.
Comparator<Apple> c1 = (a1 , a2) -> a1.getWeight().compareTo(a2.getWeight());
μ§μ λ³μ μ¬μ© λ³μ μΊ‘μ³
- λλ€ ννμμμλ μ΅λͺ ν¨μκ° νλ κ²μ²λΌ **μμ λ³μ (νλΌλ―Έν°λ‘ λκ²¨μ§ λ³μκ° μλ μΈλΆμμ μ μλ λ³μ)**λ₯Ό νμ©ν μ μλ€.
- μ΄μ κ°μ λμμ λλ€ μΊ‘μ³λ§μ΄λΌκ³ λΆλ₯Έλ€.
int portNumber = 1337;
Runnable r = () -> System.out.println(portNumber);
portNumber = 3338;
- μ§μλ³μλ λͺ
μμ μΌλ‘
final
λ‘ μ μΈλμ΄ μμ΄μΌ νκ±°λ , μ€μ§μ μΌλ‘final
λ‘ μ μΈλ λ³μμ λκ°μ΄ μ¬μ©λμ΄μΌ νλ€. - μμ μμ λ μ»΄νμΌ ν μ μλ€.
- μΈμ€ν΄μ€ λ³μλ νμ μμΉνλ©° , μ§μ λ³μλ μ€νμ μμΉνλ€.
- λλ€κ° μ€λ λμμ μ€νλλ€λ©΄ λ³μλ₯Ό ν λΉν μ€λ λκ° μ¬λΌμ Έμ λ³μ ν λΉμ΄ ν΄μ λμλλ°λ λλ€λ₯Ό μ€ννλ μ€λ λμμλ ν΄λΉ λ³μμ μ κ·Όνλ € ν μ μλ€.
- λ°λΌμ μλ° κ΅¬νμμλ μλ λ³μμ μ κ·Όμ νμ©νλ κ²μ΄ μλλΌ μμ μ§μ λ³μμ 볡μ¬λ³Έμ μ 곡νλ€.
- 볡μ¬λ³Έμ κ°μ΄ λ°λμ§ μμμΌ νλ―λ‘ μ§μ λ³μμλ ν λ²λ§ κ°μ ν λΉν΄μΌ νλ€λ μ μ½μ΄ μκΈ΄ κ²μ΄λ€.
- λ³λ ¬νλ₯Ό λ°©ν΄νλ μμκ° λ μλ μλ€.
- νΉμ λ©μλλ§μ νΈμΆνλ λλ€μ μΆμ½νμ΄λΌκ³ μκ°ν μ μλ€.
- λ©μ λ μ°Έμ‘°λ₯Ό μ΄μ©νλ©΄ κΈ°μ‘΄ λ©μλ ꡬνμΌλ‘ λλ€ ννμμ λ§λ€ μ μλ€.
- λ©μλλͺ
μμ ꡬλΆμ
::
λ₯Ό λΆμ΄λ λ°©μμΌλ‘ λ©μλ μ°Έμ‘°λ₯Ό νμ©ν μ μλ€. - μ€μ λ‘ λ©μλλ₯Ό νΈμΆνλ κ²μ μλλ―λ‘ κ΄νΈλ νμ μμμ κΈ°μ΅νμ
- λ©μλ μ°Έμ‘°λ₯Ό μλ‘μ΄ κΈ°λ₯μ΄ μλλΌ νλμ λ©μλλ₯Ό μ°Έμ‘°νλ λλ€λ₯Ό νΈλ¦¬νκ² ννν μ μλ λ¬Έλ²μΌλ‘ κ°λ μ±μ λμΌ μ μλ€.
λλ€ | λ©μλ μ°Έμ‘° λ¨μΆ νν |
---|---|
(Apple apple) -> apple.getWeight() |
Apple::getWeight |
() -> Thread.currentThread().dumpStack() |
Thread.currentThread()::dumpStack |
(str , i) -> str.substring(i) |
String::substring |
(String s) -> System.out.println(s) |
System.out::println |
(String s) -> this.isValidName(s) |
this::isValidName |
- μ μ λ©μλ μ°Έμ‘°
Integer::parseInt
...
- λ€μν νμμ μΈμ€ν΄μ€ λ©μλ μ°Έμ‘°
String
μlength
λ©μλλString::length
- κΈ°μ‘΄ κ°μ²΄μ μΈμ€ν΄μ€ λ©μλ μ°Έμ‘°
Transaction
ν΄λμ€μλgetValue
λ©μλκ° μκ³ ν΄λΉ ν΄λμ€λ₯Ό ν λΉ λ°μexpensiveTransaction
μ§μ λ³μκ° μλ€.- μ΄λ₯Ό
expensiveTransaction::getValue
ννν μ μλ€.
List<String> str = Arrays.asList("a" , "b" , "A" , "B");
str.sort((s1 , s2) -> s1.compareToIgnoreCase(s2));
str.sort(String::compareToIgnoreCase);
1. ToIntFunction<String> stringToInt = (String s) -> Integer.parseInt(s);
ToIntFunction<String> stringToInt = Integer::parseInt;
2. BiPredicate<List<String> , String> contains = (list , element) -> list.contains(element);
BiPredicate<List<String> , String> contains = List::contains;
3. // λΉκ³΅κ° ν¬νΌ λ©μλ νΈμΆ
class test{
Predicate<String> startsWithNumber = (String string) -> this.startsWithNumber(string);
Predicate<String> startsWithNumber2 = this::startsWithNumber;
private boolean startsWithNumber(String string) {
return true;
}
}
ClassName::new
μ²λΌ ν΄λμ€λͺ κ³Όnew
ν€μλλ₯Ό μ΄μ©ν΄μ κΈ°μ‘΄ μμ±μμ μ°Έμ‘°λ₯Ό λ§λ€ μ μλ€.- μ΄κ²μ μ μ λ©μλμ μ°Έμ‘°λ₯Ό λ§λλ λ°©λ²κ³Ό λΉμ·νλ€.
- μλ₯Ό λ€μ΄ μΈμκ° μλ μμ±μ ,
Supplier
μ() -> Apple
κ³Ό κ°μ μκ·Έλμ²λ₯Ό κ°λ μμ±μκ° μλ€κ³ κ°μ νμ.
@FunctionalInterface
public interface TriFunction<T , U , V , R> {
R get(T t, U u, V v);
}
class Apple{
int weight;
Color color;
String status;
int objectHashCode = this.hashCode();
public Apple() {
}
public Apple(int weight) {
this.weight = weight;
}
public Apple(int weight, Color color) {
this.weight = weight;
this.color = color;
}
public Apple(int weight, String status) {
this.weight = weight;
this.status = status;
}
public Apple(int weight, Color color, String status) {
this.weight = weight;
this.color = color;
this.status = status;
}
@Override
public String toString() {
return "Apple{" +
"weight=" + weight +
", color='" + color + '\'' +
", status='" + status + '\'' +
", objectHashCode=" + objectHashCode +
'}';
}
public enum Color {GREEN , RED , YELLOW}
}
class Main {
public static void main(String[] args) throws Exception {
Supplier<Apple> supplier1 = Apple::new;
System.out.println(supplier1.get());
Supplier<Apple> supplier2 = () -> new Apple();
System.out.println(supplier2.get());
Function<Integer , Apple> function1 = Apple::new;
System.out.println(function1.apply(11));
List<Integer> weights = Arrays.asList(21 , 22 , 23 , 24 , 25);
List<Apple> apples = map(weights , function1);
apples.forEach(System.out::println);
BiFunction<Integer , Apple.Color, Apple> biFunction1 = Apple::new;
System.out.println(biFunction1.apply(31 , Apple.Color.GREEN));
BiFunction<Integer , String , Apple> biFunction2 = Apple::new;
System.out.println(biFunction2.apply(41 , "GOOD"));
TriFunction<Integer , Apple.Color , String , Apple> triFunction1 = Apple::new;
System.out.println(triFunction1.get(51 , Apple.Color.RED , "BAD"));
// Apple{weight=0, color='null', status='null', objectHashCode=1854731462}
// Apple{weight=0, color='null', status='null', objectHashCode=214126413}
// Apple{weight=11, color='null', status='null', objectHashCode=1867750575}
// Apple{weight=21, color='null', status='null', objectHashCode=2046562095}
// Apple{weight=22, color='null', status='null', objectHashCode=1342443276}
// Apple{weight=23, color='null', status='null', objectHashCode=769287236}
// Apple{weight=24, color='null', status='null', objectHashCode=1587487668}
// Apple{weight=25, color='null', status='null', objectHashCode=1199823423}
// Apple{weight=31, color='GREEN', status='null', objectHashCode=1896277646}
// Apple{weight=41, color='null', status='GOOD', objectHashCode=1702297201}
// Apple{weight=51, color='RED', status='BAD', objectHashCode=1296064247}
}
public static List<Apple> map(List<Integer> list , Function<Integer , Apple> f){
List<Apple> result = new ArrayList<>();
for(Integer i : list){
result.add(f.apply(i));
}
return result;
}
}
- μΈμ€ν΄μ€ν νμ§ μκ³ λ μμ±μμ μ κ·Όν μ μλ κΈ°λ₯μ λ€μν μν©μ μμ©ν μ μλ€.
- μλ₯Ό λ€μ΄
Map
μΌλ‘ μμ±μμ λ¬Έμμ΄ κ°μ κ΄λ ¨μν¬ μ μλ€. - 그리κ³
String
κ³ΌInteger
κ° μ£Όμ΄μ‘μ λ λ€μν 무κ²λ₯Ό κ°λ μ¬λ¬ μ’ λ₯μ κ³ΌμΌμ λ§λλgiveMeFruit
λ©μλλ₯Ό λ§λ€ μ μλ€.
static Map<String , Function<Integer , Fruit>> map = new HashMap<>();
static{
map.put("apple" , Apple::new);
map.put("orange" , Orange::new);
...
}
public static Fruit giveMeFruit(String fruit , Integer weight){
return map.get(fruit.toLowerCase()) // mapμμ Function<Integer , Fruit>μ μ»μλ€.
.apply(weight); // Functionμ applyλ©μλμ μ μλ₯Ό μ 곡νμ¬ Fruitμ μμ±ν μ μλ€.
}
sort
μ λμμ νλΌλ―Έν°νλμλ€. (μ λ ¬ μ λ΅μ λ°λΌ λμμ΄ λ¬λΌμ§λ€.)
// List.sortμ μκ·Έλμ²
void sort(Comparator<? super E> c)
public class AppleComparator implements Comparator<Apple>{
public int compare(Apple a1 , Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
}
inventory.sort(new AppleComparator());
- ν λ²λ§ μ¬μ©ν
Comparator
λ₯Ό ꡬννκΈ° 보λ€λ μ΅λͺ ν΄λμ€λ₯Ό μ΄μ©νλ κ²μ΄ μ’λ€.
inventory.sort(new Comparator<Apple>(){
public int compare(Apple a1 , Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
});
- ν¨μν μΈν°νμ΄μ€λ₯Ό κΈ°λνλ κ³³ μ΄λμλ λλ€ ννμμ μ¬μ©ν μ μλ€.
inventory.sort((Apple a1 , Apple a2) ->> a1.getWeight().compareTo(a2.getWeight()));
- μλ° μ»΄νμΌλ¬λ λλ€ ννμμ΄ μ¬μ©λ μ½ν μ€νΈλ₯Ό νμ©ν΄μ λλ€μ νλΌλ―Έν° νμμ μΆλ‘ νκΈ° λλ¬Έμ λ μ€μΌ μ μλ€.
inventory.sort((a1 , a2) ->> a1.getWeight().compareTo(a2.getWeight()));
java.util.Comparator.comparing
μ μ μ μΌλ‘ μν¬νΈνλ€κ³ κ°μ - β
comparing()
Comparator
λComparable
ν€λ₯Ό μΆμΆν΄μComparator
κ°μ²΄λ‘ λ§λλFunction
ν¨μλ₯Ό μΈμλ‘ λ°λ μ μ λ©μλcomparing
μ ν¬ν¨νλ€.- μ΄ λ©μλκ° μ μ λ©μλμΈ μ΄μ λ 9μ₯μμ μ€λͺ νλ€.
Comparator<Apple> c = Comparator.comparing((Apple a) -> a.getWeight());
import static java.util.Comparator.comparing;
inventory.sort(comparing(apple -> a.getWeight()));
- λ©μλ μ°Έμ‘°λ₯Ό μ¬μ©νμ¬ μ½λλ₯Ό μ‘°κΈλ κ°μν νμ
inventory.sort(comparing(Apple::getWeight));
- λͺλͺ ν¨μν μΈν°νμ΄μ€λ λ€μν μ νΈλ¦¬ν° λ©μλλ₯Ό ν¬ν¨νλ€.
- κ°λ¨ν μ¬λ¬ κ°μ λλ€ ννμμ μ‘°ν©ν΄μ 볡μ‘ν λλ€ ννμμ λ§λ€ μ μλ€.
- λ Predicateλ₯Ό μ‘°ν©ν΄μ 컀λ€λ Predicateλ₯Ό λ§λ€κ±°λ,
- ν ν¨μμ κ²°κ³Όκ° λ€λ₯Έ ν¨μμ μ λ ₯μ΄ λλλ‘ λ Functionμ μ‘°ν©ν μ μλ€.
- μ΄μ κ°μ κΈ°λ₯μ κ°λ₯μΌ νλκ²μ ν¨μν μΈν°νμ΄μ€μ μ μΈλ λν΄νΈ λ©μλμ΄λ€. (9μ₯μμ μμΈν μ€λͺ )
- λν΄νΈ λ©μλκ° μ΄λ€ λ©μλμΈμ§λ§ μ΄ν΄νμ.
- μ΄μ μλ 보μλ―μ΄ , μ μ λ©μλ
Comparator.comparing
μ μ΄μ©ν΄μ λΉκ΅μ μ¬μ©ν ν€λ₯Ό μΆμΆ νλFunction
κΈ°λ°μComparator
λ₯Ό λ°νν μ μλ€.
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
Comparator<Apple> c = Comparator.comparing((Apple a) -> a.getWeight());
- μ¬κ³Όμ 무κ²λ₯Ό λ΄λ¦Όμ°¨μμΌλ‘ μ λ ¬νκ³ μΆλ€λ©΄? λ€λ₯Έ
Comparator
μΈμ€ν΄μ€λ₯Ό λ§λ€ νμκ° μλ€. - μΈν°νμ΄μ€ μ체μμ
reversed
λΌλ λν΄νΈ λ©μλλ₯Ό μ 곡νκΈ° λλ¬Έμ΄λ€.
inventory.sort(comparing(Apple::getWeight).reversed());
- 무κ²κ° κ°μ μ¬κ³Όλ μ΄λ»κ² μ λ ¬ ν΄μΌ ν κΉ?
- μ΄λ΄ λ λΉκ΅ κ²°κ³Όλ₯Ό λ λ€λ¬μ μ μλ λ λ²μ§Έ
Comparator
λ₯Ό λ§λ€ μ μλ€. thenComparing
λ©μλλ‘ λ λ²μ§Έ λΉκ΅μλ₯Ό λ§λ€ μ μλ€.
inventory.sort(comparing(Apple::getWeight)
.reversed()
.thenComparing(Apple::getCountry));
negate
,and
,or
μΈκ°μ§ λ©μλλ₯Ό μ 곡νλ€.
Predicate<Apple> notRedApple = redApple.negate();
Predicate<Apple> redAndHeavyApple = redApple.and(apple -> apple.getWeight > 150);
Predicate<Apple> redAndHeavyAppleOrGreen =
redApple.and(apple -> apple.getWeight > 150)
.or(apple -> GREEN.equals(apple.getColor()));
Function
μΈμ€ν΄μ€λ₯Ό λ°ννλandThen
,compose
λ κ°μ§ λν΄νΈ λ©μλλ₯Ό μ 곡νλ€.
Function<Integer , Integer> f = x -> x + 1;
Function<Integer , Integer> g = x -> x * 2;
Function<Integer , Integer> h = f.andThen(g);
int result = h.apply(1);
// g(f(x))
// 4λ₯Ό λ°ν
Function<Integer , Integer> f = x -> x + 1;
Function<Integer , Integer> g = x -> x * 2;
Function<Integer , Integer> h = f.compose(g);
int result = h.apply(1);
// f(g(x))
// 3μ λ°ν
- μ νΈλ¦¬ν° λ©μλλ₯Ό μ‘°ν©ν΄μ λ€μν λ³ν νμ΄ν λΌμΈμ λ§λ€ μ μλ€.
Function<String , String> addHeader = Letter::addHeader;
Function<String , String> transformationPipeline =
addHeader.andThen(Letter::checkSpelling)
.andThen(Letter::addFooter);
- μ΅λͺ
ν΄λμ€μμ μ¬μ©ν
this
μsuper
λ λλ€ ννμμμ λ€λ₯Έ μλ―Έλ₯Ό κ°λλ€. μ΅λͺ ν΄λμ€μμ thisλ μ΅λͺ ν΄λμ€ μμ μ κ°λ¦¬ν€μ§λ§ λλ€μμ thisλ λλ€λ₯Ό κ°μΈλ ν΄λμ€λ₯Ό κ°λ¦¬ν¨λ€. - μ΅λͺ ν΄λμ€λ κ°μΈκ³ μλ ν΄λμ€μ λ³μλ₯Ό κ°λ¦¬ν¬ μ μλ€. (μλμ° λ³μ)
int a = 100;
Runnable r1 = () -> {
int a = 10; // μ»΄νμΌ μλ¬
System.out.println(a);
};
Runnable r2 = new Runnable() {
@Override
public void run() {
int a = 10;
System.out.println(a);
}
};
- λλ€ ννμμ μ΅λͺ
ν¨μμ μΌμ’
μ΄λ€.
- μ΄λ¦μ μμ§λ§ , νλΌλ―Έν° 리μ€νΈ , λ°λ , λ°ν νμμ κ°μ§λ©° μμΈλ₯Ό λμ§ μ μλ€.
- ν¨μν μΈν°νμ΄μ€λ νλμ μΆμ λ©μλλ§μ μ μνλ μΈν°νμ΄μ€λ€.
- ν¨μν μΈν°νμ΄μ€λ₯Ό κΈ°λνλ κ³³μμλ§ λλ€ ννμμ μ¬μ©ν μ μλ€.
- λλ€ ννμμ μ΄μ©ν΄μ ν¨μν μΈν°νμ΄μ€μ μΆμ λ©μλλ₯Ό μ¦μμΌλ‘ μ 곡ν μ μμΌλ©° λλ€ ννμ μ μ²΄κ° ν¨μν μΈν°νμ΄μ€μ μΈμ€ν΄μ€λ‘ μ·¨κΈλλ€.
- μλ° 8μ μ λ€λ¦ ν¨μν μΈν°νμ΄μ€μ κ΄λ ¨ν λ°μ± λμμ νΌν μ μλ κΈ°λ³Έν νΉν μΈν°νμ΄μ€κ° μ 곡λλ€.
- μ€ν μ΄λΌμ΄λ ν¨ν΄ *(μμμ ν λΉ , μμ μ 리 λ± μ½λ μ€κ°μ μ€νν΄μΌ νλ λ©μλμ κΌ νμν μ½λ)*μ λλ€μ νμ©νλ©΄ μ μ°μ±κ³Ό μ¬μ¬μ©μ±μ μ»μ μ μλ€.
- λλ€ ννμμ κΈ°λ νμμ λμ νμ μ΄λΌκ³ νλ€.
- λ©μλ μ°Έμ‘°λ₯Ό μ΄μ©νλ©΄ κΈ°μ‘΄μ λ©μλ ꡬνμ μ¬μ¬μ©νκ³ μ§μ μ λ¬ν μ μλ€.
- μλ°μμ μ 곡λλ ν¨μν μΈν°νμ΄μ€μ μΆμ λ©μλλ€μ μ²΄ν¬ μμΈλ₯Ό
throws
νκ³ μμ§ μκΈ° λλ¬Έμ μ§μ throws
λ₯Ό νλ μΆμ λ©μλλ₯Ό κ°μ§ ν¨μν μΈν°νμ΄μ€λ₯Ό μ μΈνλμ§, λλ€ κ΅¬νμμtry/catch
λ₯Ό μ μΈν΄μ€μΌ νλ€.