ëë€ííìì ìµëª íŽëì€ì²ëŒ ìŽëŠìŽ ìë íšììŽë€.
ë©ìë륌 ìžìë¡ ì ë¬í ì ìë ì¹êµ¬ì ëë€.
ëë€ ì©ìŽ ì첎ë 믞ì ë¶í íê³ìì ì ëëìëµëë€.
ì€ëì ëë€ ëë€íë ê·ž ëë€ì ëíŽì ì 늬íŽë³Žë €ê³ í©ëë€.
몚ëìë°ìžì¡ì ì± ì¬ëíŽì
1. ëë€ë 묎ììžê°?
ëë€ ííì: ë©ìëë¡ ì ë¬í ì ìë ìµëª íšì륌 ëšìíí ê².
ëë€ í¹ì§
- 1) ìµëª ìŽë€. ë©ìëì ë€ë¥Žê² ìŽëŠìŽ ìë€.
- 2) íšììŽë€. í¹ì íŽëì€ì ì¢ ìëì§ ìëë€. ê·žëì íšìëŒê³ ë ë¶ëŠŒ. íì§ë§ ë©ìëì í¹ì§ ëí ê°ì§.
- 3) ì ë¬ìŽ ê°ë¥íë€. ëë€ ííìì ë©ìë ìžìë¡ ì ë¬íê±°ë ë³ìë¡ ì ì¥ ê°ë¥.
- 4) ê°ê²°íë€. ìµëª íŽëì€ì²ëŒ ì€ë³µëê±°ë íŽëì€ ìì±ì ìí ìœë륌 구íí íì ìì.
cf) ë©ìëì í¹ì§ì?
- íëŒë¯ží° 늬ì€íž, ë°ë, ë°í íì, ììž ëŠ¬ì€íž í¬íš.
@Test
@DisplayName("Comparator ëë€ë¡ ë³í")
void comparatorTest() {
Comparator<Apple> appleComparator = new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return o1.getWeight()> o2.getWeight()?o1.getWeight():o2.getWeight();
}
};
Comparator<Apple> lamdaComparator = (o1, o2) -> o1.getWeight()> o2.getWeight()?o1.getWeight():o2.getWeight();
}
ìëìì ì€ëª ì í í ì§ë§, ëë€ë ìì ê°ìŽ ìŽë€.
ëë€ ë ëë° ìŽë»ê² ì°ë 걎ë°.
ê·žë¬ë©Ž ëë€ë ìŽë»ê² ì¬ì©íŽìŒ ë ê¹.
ëë€ ííì ì€íìŒ í¹ì§ 1)
ëë€ ííìì íëŒë¯ží°, íìŽí, ë°ëë¡ êµ¬ì±ëë€.
(o1, o2) -> o1.getWeight()> o2.getWeight() ?o1.getWeight():o2.getWeight();
- (o1, o2) : ëë€ íëŒë¯ží°. íëŒë¯ží° 늬ì€íž. Comparatorì compare ë©ìë íëŒë¯ží°
- -> : íìŽíë ìŒìªœì¢ë íëŒë¯ží° 늬ì€íž, ì€ë¥žì¢ë ë°ë륌 구ë¶íš. 구ë¶ì¢ì.
- ì€ë¥žìªœ 구묞: ëë€ ë°ëìŽë€. ë°í ê°ì íŽë¹íë ííì.
return êµ¬ë¬žìŽ ì¬ëŒì ž ìë€. ê·žë ë€. ëë€ ííìììë returnì ì¬ì©íì§ ììë ëë€.
ëë€ ííì ì€íìŒ í¹ì§ 2)
ëë€ ííì ìììë ì¬ë¬ ì€ ííë ê°ë¥íë€.
@Test
@DisplayName("ëë€ ííì ìì ")
void lamdaExample() {
Comparator<Integer> integerComparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println("Lamda.compare. ì¬ë¬ ì€ìŽ ê°ë¥íë€!");
System.out.println("Lamda.compare. ì¬ë¬ ì€ìŽ ê°ë¥íë€!");
return 0;
}
};
Comparator<Integer> integerComparator2 = (o1, o2) -> {
System.out.println("Lamda.compare. ì¬ë¬ ì€ìŽ ê°ë¥íë€!");
System.out.println("Lamda.compare. ì¬ë¬ ì€ìŽ ê°ë¥íë€!");
return 0;
};
}
ëë€ ííì ì€íìŒ í¹ì§ 3)
(parameter) -> expression
(parameters) -> { statements; }
ëë€ ííììŽ ê°ëší í ì€ìž 겜ì°ìë ì€êŽížë¥Œ ìëµí ì ìë€.
(Integer i) -> return i; // í늌!
(Integer i) -> { return i; } // ë§ì!
íì§ë§, ìœë ëžë¡ìŽ ì¬ë¬ ì€ë¡ ìŽë£šìŽì ž ìê±°ë ëª ìì ìž ë°íì íŽìŒ íë 겜ì°ìë ì€êŽížë¥Œ ì¬ì©íì¬ ìœë ëžë¡ì ì ìíŽ ì€ìŒ íëë€.
cf) íëŠ ì ìŽë¬ž returnì ìëµí ì ìë€
íìŽì¬ììì ííì(expression)ìŽ ìë 묞ì¥ììë ë³Žíµ returnìŽ ìëµë ì ìë€.
ìŽì²ëŒ, ííìì ìëì ìŒë¡ ì¶ë¡ í ì ìêž° ë묞ì ëª ìì ìž return 묞ì ì¬ì©íì§ ììë ëë€ íšìë ííìì 결곌륌 ë°ííŽ ì€ë€.
add = lambda x, y: x + y
result = add(3, 5)
print(result) # ì¶ë ¥: 8
2. ëë€ ì¬ì©ë²
ëë€ ííìì íšìí ìží°íìŽì€/íšì ëì€í¬ëŠœí°ë¡ ì¬ì©í ì ìë€
1) íšìí ìží°íìŽì€
ìë°ì íšìí ìží°íìŽì€ë ë€ìíê² ììµëë€. íšìí ìží°íìŽì€ë íëì ì¶ìë©ìë륌 ì§ì íë ìží°íìŽì€ì ëë€.
ìë° APIì íšìí ìží°íìŽì€ë Comparator, Runnale, Predicate ë±ìŽ ììµëë€.
ê·žì€, Predicate íšìí ìží°íìŽì€ë ìëì ê°ìŽ ì게ìµëë€ëë€.
public interface Predicate<T> {
boolean test (T t);
}
ì íšì ìží°íìŽì€ ìêž°ê° ëììê¹.
ëë€ ííìì íšìí ìží°íìŽì€ì ìžì€íŽì€ë¡ ë§ë€ ì ìêž° ë묞ìŽë€.
ì ííë íšìí ìží°íìŽì€ë¥Œ 구íí íŽëì€ì ìžì€íŽì€ë¡ ë§ë€ ì ìë€ëë€.
ìµëª ëŽë¶ íŽëì€ë 구í ê°ë¥í©ëë€.
public static void process(Runnable runnable) {
runnable.run();
}
@Test
@DisplayName("ëë€ ííììŒë¡ íšìí ìží°íìŽì€ ì ë¬")
void functionalInterface() {
Runnable runnable1 = new Runnable() {
@Override
public void run() {
System.out.println("Lamda.run");
}
};
Runnable runnable2 = () -> System.out.println("Lamda.functionalInterface");
process(runnable1);
process(runnable2);
process(()-> System.out.println("Lamda.functionalInterface ì§ì ëë€ë¡ ì ë¬"));
}
Runnableì íšìí ìží°íìŽì€êž° ë묞ì, ëë€ ííììŒë¡ 구íìŽ ê°ë¥íë€.
íëì ì¶ì ë©ìëìž run() ë©ìëë§ ê°ì§ê³ ìêž° ë묞ìŽë€.
2) íšì ëì€í¬ëŠœí°
íšì ëì€í¬ëŠœí°? ëë€ ííìì ìê·žëì²ë¥Œ ìì íë ë©ìëìŽë€.
ëë€ ííìì ìê·žëì²? íšìí ìží°íìŽì€ì ì¶ì ë©ìë ìê·žëì²ìŽë€.
ìŠ, íšìí ìží°íìŽì€ì ì¶ì ë©ìë ìê·žëì²ë¥Œ ìë©Ž, ê·ž ìží°íìŽì€ë¥Œ ëë€ ííììŒë¡ ííí ë
íìí 맀ê°ë³ì íì ë° ë°í íì ì ìŽíŽí ì ìë€ë¥.
ì¶ê° ì€ëª íŽ ë³Žìë©Ž, ìê·žëì²ë íšìì íì ìŽë€. ëë€ê° ìë ìŒë° ë©ìëììë ì¬ì©íë ì©ìŽë€.
ëë€ ë§ê³ , ìŒë° ë©ìë륌 íµíŽ ìê·žëì²ë¥Œ ëŽë³Žê² ë€.
public int add(int x, int y) {
// ë©ìë 볞묞
}
ë©ìëì ìê·žëì²ë add(int x, int y)ìŽë€.
ìŽë¥Œ íµíŽ ë©ìëì ìŽëŠìŽ "add"ìŽê³ íëŒë¯ží°ë ë ê°ì ì ì륌 ë°ê³ , ë°í íì ì ì ì(int) ìì ì ì ìë€.
Runnable myRunnable = () -> {
// ì€í ìœë
};
ëë€ì ìê·žëì² ìì ë ëŽë³Žì.
ëë€ ííìì ìê·žëì²ë () -> voidë€.
ìŽê²ì íëŒë¯ží°ë¥Œ ë°ì§ ìê³ , ë°íê°ìŽ ìë íšì구ë~~ëŒë ê²ì ìê·žëì²ë¥Œ íµíŽ ì ì ìë€.
ì 늬íìë©Ž, ë€ì곌 ê°ë€.
- () -> void íêž°: íëŒë¯ží° 늬ì€ížê° ììŒë©° void륌 ë°ííë íšì륌 ì믞íš.
(Apple, Apple) -> int
: ë ê°ì Apple륌 ìžìë¡ ë°ì int륌 ë°ííë íšìë ë»ìŽììŽ~
=> ëë€ ííìì ë³ìì í ë¹íê±°ë íšìí ìží°íìŽì€ë¥Œ ìžìë¡ ë°ë ë©ìëë¡ ì ë¬í ì ìì.
ìŽì¯€ ëë©Ž, ê¶êžíŽì§ë€. ì íšìí ìží°íìŽì€ë¥Œ ìžìë¡ ë°ë ë©ìëìë§ ëë€ ííììŽ ì¬ì© ê°ë¥íì§.
ìŽì ë ìžìŽ ì€ê³ìë€ìŽ ë³µì¡íì§ ìê³ ë ìµìí ë°©ë²ì ì¬ì©í ì ìëë¡ íë€ê³ íš.
cf) í·ê°ë žë ê±°
- íšì ëì€í¬ëŠœí°ë ëë€ ííìì íì ì ì€ëª íêž° ìí ê°ë
- ì€ì ë¡ ìœëììë íšì ëì€í¬ëŠœí°ë¥Œ ì§ì ì¬ì©íë ê²ì ìë!!
- ëë€ ííìì íµíŽ 컎íìŒë¬ê° ìëìŒë¡ íšì ëì€í¬ëŠœí°ë¥Œ ì ì¶íêž° ìí ê²ì.
cf) ë©ìëì ìê·žëì²
ë©ìëì ìê·žëì²ë ë©ìë륌 ìë³íë ë° ì¬ì©ëë ì 볎륌 ëíëžë€.
ë©ìëì ìŽëŠ, 맀ê°ë³ìì íì
곌 ìì, ë°í íì
ë±ì í¬íšíëë°, ë©ìëê° ížì¶ë ë ìŽë€ 맀ê°ë³ì륌 ë°ìë€ìŽê³ ìŽë€ íì
ì ê°ì ë°ííëì§ì ëí ì 볎륌 ëŽê³ ìë€.
[ì ê·Œ ì ìŽì] [ë°í íì
] ë©ìë ìŽëŠ(맀ê°ë³ì íì
1 맀ê°ë³ì ìŽëŠ1, 맀ê°ë³ì íì
2 맀ê°ë³ì ìŽëŠ2, ...)
- ì ê·Œ ì ìŽì(Access Modifier):ë©ìëì ëí ì ê·Œ ê¶í. ex) public, private
- ë°í íì (Return Type): ë©ìëê° ë°ííë ê°ì ë°ìŽí° íì . ex) void
- ë©ìë ìŽëŠ(Method Name): ë©ìëì ìŽëŠ
- 맀ê°ë³ì(Parameter): ë©ìëê° ë°ë ì ë ¥ ê°ë€ì ì ì
ìŠ, ìë°ìì ìê·žëì²ë ë©ìëë íšìì ìŽëŠ, 맀ê°ë³ìì íì , ê·žëŠ¬ê³ ë°í íì ì íµíŽ ì ìëëë°,
ìê·žëì²ë¥Œ íµíŽ ìœë륌 ìŽíŽíê³ ì ì§ë³Žìíë ë° ëììŽ ëë€.
3) ëë€ íì©ë²: ì€í ìŽëŒìŽë íšíŽ
ì€í ìŽëŒìŽë íšíŽìŽë?
ì€ì ììì ì²ëŠ¬íë ìœë륌 ì€ì 곌 ì 늬 ë 곌ì ìŽ ëë¬ìŒ íí륌 ë§íë€.
ì€í ìŽëŒìŽë íšíŽì íì©í ìì 륌 ëŽë³Žì.
public String processFile() throws Exception {
try(
BufferedReader bufferedReader = new BufferedReader(new FileReader("data.txt"))) {
return bufferedReader.readLine();
}
}
ìŽë¥Œ íšìí ìží°íìŽì€ì ëë€ë¥Œ ìŽì©íŽì ì ë¬íŽ 볎ì.
@FunctionalInterface
public interface BufferReaderProcessor {
String process(BufferedReader bufferedReader) throws IOException;
}
@Test
@DisplayName("ì€í ìŽëŒìŽë íšíŽ")
void excuteAroundPattern() throws FileNotFoundException {
// processFile() íšìì ëìì íëŒë¯ží°í
//String result = processFile(new BufferedReader(new FileReader("example.txt")));
// íšìí ìží°íìŽì€ë¡ ì ë¬
String result2 = processFile((BufferedReader br) -> {
try {
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
return null;
}
});
}
íšìí ìží°íìŽì€ë¡ ë°ê¿ì íŽëŽ€ë€.
ê·žë¬ë©Ž ë ì€ì ì²ëŠ¬íë ìœëë ìì± ê°ë¥íë€.
String twoLineResult = processFile((BufferedReader bufferReader) -> bufferReader.readLine() + bufferReader.readLine());
3. íšìí ìží°íìŽì€ ì¬ì©
íšìí ìží°íìŽì€ ë³ë êž ì°žê³ !
ì€ìí ì ì, íšìí ìží°íìŽì€ë ì€ì§ íëì ì¶ì ë©ìë륌 ì§ì íë€.
ê·žëŒ ìŽ ì¶ì ë©ìëë ëë€? ëë€ ííìì ìê·žëì²ë¥Œ ë¬ì¬íê² ëë€.
ìŽë¥Œ íšì ëì€í¬ëŠœí°ëŒê³ íë€. ìë ë€ìì ë€ì ë ì€ëª íê² ë€.
ì묎íŒ! ê³µíµì íšì ëì€í¬ëŠœí°ë¥Œ êž°ì íë íšìí ìží°íìŽì€ ì§í©ìŽ ììŽìŒ ë€ìí ëë€ ííì ì¬ì©ìŽ ê°ë¥íë€.
ìë° 8 ëŒìŽëžë¬ëŠ¬ìë java.util.function íší€ì§ë¡ ìë° APIì Comparable, Runnable, Callable ë±ì ì¬ë¬ ê°ì§ ìë¡ìŽ íšìí ìží°íìŽì€ë¥Œ ì ê³µíë¹.
ìë€ë¥Œ ìŽë»ê² ì¬ì©íŽìŒ íëì§ ì°ìµíë©Ž ëëë€.
1. Predicate
java.util.function.Predicate<T>
ìží°íìŽì€ë test() ëŒë ì¶ì ë©ìë륌 ì ìíë€.
boolean ííììŽ íìí ë Predicate ìží°íìŽì€ë¥Œ ì¬ì©í ì ìë€.
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
public <T> List<T> filter(List<T> list, Predicate<T> predicate) {
List<T> results = new ArrayList<>();
for (T t : list) {
if(predicate.test(t)) {
results.add(t);
}
}
return results;
}
@Test
@DisplayName("Predicate ìì ")
void predicateExample() {
Predicate<String> emptyStringPredicate = (String s) -> s.isEmpty();
List<String> stringList = new ArrayList<>();
stringList.add("TEST");
stringList.add("TEST2");
List<String> emptyStringList = filter(stringList, emptyStringPredicate);
assertEquals(emptyStringList.size(), 0);
}
2. Consumer
java.util.function.Consumeer<T>
ìží°íìŽì€ë void륌 ë°ííë accept ëŒë ì¶ì ë©ìë륌 ì ìíš.
Consumerì ëšìŽì ë»ì ìë¹ì, ìë¹íë€ë ë»ìŽììŽ?
ëšìŽ ë» ê·žëë¡, ë°íê°ë ìê³ ì ë§ ì¶ì ë©ìëë¡ ëꞎ ëìë§ ìííŽ ì€.
ë§€ì° ì¿ší ë ìì.
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
public <T> void printMessage(T printMsg, Consumer<T> consumer) {
consumer.accept(printMsg);
}
@Test
@DisplayName("Consumer ìì ")
void consumerExample (){
printMessage(12345, (Integer msg) -> System.out.println("Integer Lamda.consumerExample"));
printMessage("ìë¹íŽë²ëŠŽí
ë€", (String msg) -> System.out.println("String Lamda.consumerExample"));
}
ì ìì ë, ê°ëšíê² íëŒë¯ží°ë¡ ëꞎ ë©ìì§ë¥Œ íëŠ°íž ë¬žìŒë¡ ì¶ë ¥íë ìì ë¹
íëŒë¯ží°ì íì 곌 묎êŽíê², ëë€ë¡ ëꞎ ëìì ì±ì€í ìííŽ ì€ ê²ì íìží ì ìë€.
3. Function
java.util.function.Function<T, R>
ìží°íìŽì€ë T륌 ìžìë¡ ë°ìì R ê°ì²Žë¥Œ ë°ííŽ ì£Œë ì¶ì ë©ìë apply륌 ì ìíš.
ì ë ¥ì ì¶ë ¥ìŒë¡ 맵ííë ëë€ë¥Œ ì ìí ë íì©í ì ìë€.
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
public <T, R> R applyMsg(T msg, Function<T, R> function) {
return function.apply(msg);
}
@Test
@DisplayName("Function ìì ")
void functionExample() {
Integer result = applyMsg("ìë
íìžì~", (String msg) -> msg.length());
assertEquals(6, result);
}
ë°ë¡ ìë ê².
ì ìì ë íëŒë¯ží°ë¡ ëꞎ 묞ììŽì êžžìŽë¥Œ ê²°ê³Œë¡ ë°ë ìì ìŽë€.
cf) íšìí ìží°íìŽì€ íì
ììì 볞 Predicate, Consumer, Function<T, R> íšìí ìží°íìŽì€ë Ʞ볞í ìží°íìŽì€ë€.
ì ë€ëŠ(Të R) íëŒë¯ží°ìë ì°žì¡°í!! ë§ ì¬ì©ìŽ ê°ë¥íë€. (ëŽë¶ 구í ë묞ì ê·žë ë€ê³ íš)
ë¬Œë¡ ìë°ììë Ʞ볞í->ì°žì¡°íìŒë¡ ë³ííë êž°ë¥ì ì ê³µíš.
Ʞ볞í, ì°žì¡°íì ìëì ê°ë€.
- Ʞ볞í: int, double, byte, char ë±
- ì°žì¡°í: Object, Integer, List ë±
@Test
@DisplayName("ì°žì¡°íì Ʞ볞íìŒë¡ ìžë°ì±")
void unboxTest() {
Integer integer = 100;
int intValue = integer;
assertEquals(100, intValue);
}
@Test
@DisplayName("Ʞ볞íì ì°žì¡°íìŒë¡ ë°ì±")
void boxTest() {
int intValue = 100;
Integer integer = intValue;
assertEquals(100, integer);
}
ë묎 íží êž°ë¥ìŽë€. ì€í ë°ì± ìŽëŒê³ ë íë€.
ê·Œë° íë¡ê·žëëšžê° íží ê²ì ëë€? 컎íší°ê° ê³ ì ì€ìŽë€~ ê³ ì ì€ì ëë€? ë©ëªšëŠ¬ë¥Œ ë ìë¹íë€~
ìëë©Ž, ë°ì±í ë Ʞ볞íì ê°ìžì íì ì ì¥íëë°(ë©íìŽëŒê³ íš), ê·žëì ë©ì¹ê° ì»€ì žì ë©ëªšëŠ¬ë¥Œ ë ìë¹íë€.
íì ì ì¥íê² ëë©Ž, ë€ì Ʞ볞íì ê°ì žì¬ ëë ë€ì íë² ë©ëªšëŠ¬ë¥Œ íìíë 곌ì ìŽ íìíê² ëë€.
ê·žëì, ìŽë° ì€í ë°ì± ëìì íŒíêž° ìí ìë° 8ì íšìí ìží°íìŽì€ê° ì ê³µëë€.
@FunctionalInterface
public interface IntPredicate {
boolean test(int t);
}
@Test
@DisplayName("IntPredicateë¡ ì€í ë°ì± ìíêž°")
void intPredicateExample() {
IntPredicate intPredicate = (int i) -> i+100 > 0;
Predicate<Integer> integerPredicate = (Integer integer) -> integer+100 > 0;
assertEquals(true, intPredicate.test(100));
assertEquals(true, integerPredicate.test(100));
}
ìŽë ê² ì¬ì©í ì ìì.
ì ë€ëŠ íì ì ì¬ì©íì§ ìê³ í¹ì íìì ë°ë íšìí ìží°íìŽì€ìž ê² ã·ã·
IntPredicate ë§ê³ ë DoublePrediacte, IntConsumer, IntFunction ë±ì íììŒë¡ ì¬ì© ê°ë¥íë€.
ë ê°ì ì ë€ëŠì ì¬ì©íë Function<T, R>ì ToIntFunction ê°ì íììŒë¡ë ìŽë€.
ë€ë¥ž íšìí ìží°íìŽì€ë ë€ì ê³µë¶íŽìŒê² ë¹.
ììž, ëë€, íšìí ìží°íìŽì€
íšìí ìží°íìŽì€ë ììž ëìì ì²ëŠ¬íì§ ìëë€.
ê·žë¬ë©Ž ììžë¥Œ ìŽë»ê² ì²ëŠ¬íëë?
@FunctionalInterface
public interface bufferReader {
String process(BufferedReader bufferedReader) throws IOException;
}
@Test
@DisplayName("íšìí ìží°íìŽì€ ììž ì²ëŠ¬ íêž°")
void exceptionFunctionInterface () {
Function<BufferedReader, String> function = (BufferedReader bufReader) -> {
try {
return bufReader.readLine();
} catch (IOException e) {
throw new RuntimeException(e);
}
};
}
try-catch ëžë¡ìŒë¡ ê°ìžì íŽì£Œë©Ž ëš.
4. íì ì¶ë¡
ìì ë¡ íì ì¶ë¡ ì íŽë³Žì.
ìëì ê°ì Comparator ê°ì²Ž ë§ëë ìœëê° ìë€.
Comparator<Apple> c = (a1, a2) -> a1.getWeight().compareTo(a2.getWeight());
ìŽë¥Œ íšì ëì€í¬ëŠœí°, ìê·žëì², ìœí ì€ížë¡ ì€ëª í ì ììž°.
1. ìœí ì€íž
ìœí ì€ížë ì£Œë³ í겜ìì ëë€ê° ì€íëë 묞맥ìŽë€.
ì¬êž°ìì ëë€ ííìì Comparator<Apple>
륌 ì ìíê³ ìë€.
ë°ëìë compare
ë©ìëì ë¡ì§ìŽ 볎ìžë€.
ìŽ ëë€ ííìì Apple
ê°ì²Žì 묎ê²ë¥Œ êž°ì€ìŒë¡ ë¹êµíë구ë~ ëŒë ê²ì ì ì ìë€.
ìœí ì€ížë¡ ëë€ì íëŒë¯ží° íìì ì ì ìì. ê·žë¬ë©Ž íšì ëì€í¬ëŠœí°ë¥Œ ì ìí ì ìì!!
2. íšì ëì€í¬ëŠœí°
íšì ëì€í¬ëŠœí°ë (Apple, Apple) -> int
ì.
ìŽë Comparator
ì compare
ë©ìëê² êµ¬ë~ 륌 ì ì ìì.
compare
ë©ìëë ë ê°ì Apple
ê°ì²Žë¥Œ ë¹êµíê³ ì ì륌 ë°íí ê² ëí ìì ê°ë¥íš.
ìœí ì€ížë¡ íšì ëì€í¬ëŠœí°ë¥Œ ì ì ìê³ , 컎íìŒë¬ë íšì ëì€í¬ëŠœí°ë¡ ìê·žëì² ì¶ë¡ ìŽ ê°ë¥íŽì§.
ê·žëì ë¬žë² ìëµìŽ ê°ë¥íŽì§.
3. ìê·žëì²
ëë€ ííìì ìê·žëì²ë (a1, a2)
ë¡ ììíê³ , ì€ë¥žìªœì a1.getWeight().compareTo(a2.getWeight())
ë ë©ìë 볞묞ìŽë€.
ì¬êž°ì (a1, a2)
ë 맀ê°ë³ì 목ë¡ìì ì ì ìë€.
ë°ëŒì ì 첎 ëë€ ííìì ìê·žëì²ë (a1, a2) ->
ê° ëìê² ë€.
ê¹ì ììœ
- 죌ìŽì§ ìœëë
Comparator<Apple>
륌 ì ìíë€. - íšì ëì€í¬ëŠœí°ë
(Apple, Apple) -> int
- ëë€ ííìì ìê·žëì²ë
(a1, a2) ->
- ìœí
ì€ížë
compare
ë¡ ë©ìëì ë¡ì§ì ì ê³µíëComparator
ìží°íìŽì€ì 구íìŽë€.
5. ì§ì ë³ì ì¬ì©
ëë€ ííìììë ìì ë³ìë ì¬ì© ê°ë¥íë€.
ëšìŽê° ì¢ ìŽë €ìŽë°; ê·žë¥ int a=1
ëŒê³ ì°ë©Ž aê° ìì ë³ìì.
ëë€ìì ìì ë³ì륌 ì¬ì©íë©Ž ëë€ ìº¡ì³ë§ìŽëŒê³ íš.
@Test
@DisplayName("ëë€ ìº¡ì³ë§")
void lamdaCapture () {
int number = 12345;
Runnable runnable = () -> System.out.println(number);
}
ê·Œë°, ëë€ìì ì§ì ë³ì륌 ì¬ì©í ëë 죌ìí ì ìŽ ìë€.
ì§ì ë³ì륌 finalë¡ ì ìžíê±°ë finalë¡ ì·šêžíŽìŒ íë€.
@Test
@DisplayName("ëë€ ì§ìë³ìë final ì²ëŒ ì·šêž ëìŽìŒ íë€.")
void localVarLamdaTest () {
int a = 10;
int b = 20;
Runnable runnable = () -> System.out.println(a+b);
System.out.println(a);
}
java 8 ìŽì ìë final int a = 10;
ì²ëŒ finalë¡ ì ìžì íŽì€ìŒ íì§ë§, java 8ììë ì ìžì ìëµìŽ ê°ë¥íë€. (ìŽë¥Œ effectively final ìŽëŒê³ íš)
ì ìì ë a, b ì§ì ë³ìê° í ë²ë§ ê°ìŽ ë³ê²œëê³ ì€ì§ì ìŒë¡ finalë¡ ëìíêž° ë묞ì ëë€ ë¬žìì ì€ë¥ê° ë°ìíì§ ìëë€.
íì§ë§ ê°ì ë³ê²œìŽ ìŒìŽëë©Ž ì¬ì©í ìê° ììµë€ë€.
@Test
@DisplayName("ëë€ ì§ìë³ìë final ì²ëŒ ì·šêž ëìŽìŒ íë€.")
void localVarLamdaTest () {
int a = 10;
int b = 20;
a = 30;
Runnable runnable = () -> System.out.println(a+b); // Error!!
System.out.println(a);
}
ìë¬ê° ë°ìíë€.
ì ê·žëŽê¹?
ìŽì ë, ëë€ ííììŽ íŽë¡ì 륌 íì±í ë íŽë¹ ë³ìì ê°ì ì ì¥íêž° ë묞ìŽë€.
cf) íŽë¡ì
ìœë ëžë¡ ììì ìì ë¡ê² ì ê·Œí ì ìë ìžë¶ ë²ìì ë³ììŽë€.
ëë€ë ìžë¶ ë³ìì ê°ì ë³µì¬íŽì ì¬ì©íë€. ê°ë§!! ë³µì¬íë€.
íŽë¡ì ë ìì ìŽ ì ìë ë²ì(scope)ìì ìžë¶ ë³ìì ì ê·Œí ì ìëë°, ìŽë¥Œ ìíŽ ëë€ë íŽë¹ ë³ìì ê°ì final ëë effectively finalë¡ ë§ë€ìŽ ë³µì¬íë€.
ë³µì¬ë¥Œ íµíŽ ëë€ ííìì ê·ž ê°ì ê³ ì ë ìíë¡ ì ì§íë©° ì¬ì©ìŽ ê°ë¥íëë€.
ë°ëŒì ëë€ê° ì¬ì©ë ëì ë³ì ê°ê³Œ ëë€ê° ì€íë ëì ë³ì ê°ìŽ íì ê°ê² ëë€.
ê·žëŒ ëê° ì¢ìŒë. ì€ë ë ìì ì±ìŽë ììž¡ ê°ë¥í ëììŽ ë³Žì¥ë©ëë€.
ë€ë¥ž ì€ë ëìì ìŽ ë³ìì ê°ì ë³ê²œ 못íê² íŽì ììž¡ ê°ë¥í 결곌륌 ì»ëë¡ ë³Žì¥íë ê²ì.
ë§ìœ ëë€ê° ë³ìì ì°žì¡°ê° ìëëŒ ê°ì ì§ì ë³ê²œíë€ë©Ž 묞ì ê° ë°ìí ì ìì ê²ì..
ì 늬íìë©Ž, ëë€ ííììŽ ì€ë ë ìì ì±ê³Œ ììž¡ ê°ë¥í ëìì 볎ì¥íêž° ìíŽ ìŽë° ì ìœì ëê³
final ëë effectively final ë³ì륌 ì¬ì©íšìŒë¡ìš ëë€ ííììŽ íŽë¡ì ë¡ ëìí ë ë³ìì ê°ìŽ ë³íì§ ìì ììì¹ ëª»í ëìì ë°©ì§í ì ìë€ëë€~
6. ë©ìë ì°žì¡°
ë©ìë ì°žì¡° ë°©ììŒë¡ ëë€ì²ëŒ ì¬ì©í ì ìë€.
ë©ìë ì°žì¡°ë ìœë륌 ê°ê²°íê² ë§ë€ê³ ê°ë ì±ì í¥ìíë ë° ëììŽ ëë Java 8ì êž°ë¥ ì€ íëìŽë€.
ë¬Œë¡ ìŽê±°ë íëì ë©ìëë§ ížì¶í ë ê°ë¥íë€.
ìë ì°ëŠ¬ê° ìë ëë€ ííìì ììë¡ ë€ìŽë³Žë©Ž ë€ì곌 ê°ë€.
List<String> words = Arrays.asList("apple", "banana", "orange");
// ëë€ ííìì ì¬ì©íì¬ ë¬žììŽì êžžìŽë¥Œ ë°í
List<Integer> lengths = words.stream()
.map(s -> s.length())
.collect(Collectors.toList());
ìŽë¥Œ ë©ìë ì°žì¡°ë¡ ë°ê¿ë³Žë©Ž?
List<String> words = Arrays.asList("apple", "banana", "orange");
// ë©ìë 찞조륌 ì¬ì©íì¬ ë¬žììŽì êžžìŽë¥Œ ë°í
List<Integer> lengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
ì§ -! String::length
ìœëê° ë°ëìë€.
ëë ëë€ë ì²ì ì¬ì©í ëë ì°ž ë§ìŽë ì€ì¬ëë€.ëŒê³ ìê°íëë°, ë©ìë 찞조륌 볎ë, ìë° ì€ê³ìë€ìŽ ë ì€ìŽê³ ì¶ìŽ í구ë... ì¶ìë€.
ë©ìë ì°žì¡°ê° ì€ìí ìŽì ë í¬ê² 4ê°ì§ë€.
- ê°ë ì± í¥ì: ë©ìë ì°žì¡°ë ìœë륌 ê°ê²°íê² ë§ë€ìŽ ê°ë ì±ì í¥ìíë€. í¹í ëë€ ííììŽ ë©ìë륌 ížì¶íë ê°ëší 겜ì°ì íŽë¹í©ëë€. ë¶íìí ëë€ ííìì ì€ìŽê³ , ìœëì ìë륌 ë ëª ííê² ì ë¬í ì ìì
- ì¬ì¬ì©ì± ìŠê°: ë©ìë 찞조륌 ì¬ì©íë©Ž êž°ì¡Žì ë©ìë륌 ë€ë¥ž ìœí ì€ížìì ì¬ì¬ì©í ì ììµëë€. ìœë륌 ìì±í ë í¹ì ë©ìë륌 ê°ëŠ¬í€ë ê²ìŒë¡, íŽë¹ ë©ìëì ë¡ì§ì ë³ê²œíì§ ìê³ ë ìë¡ìŽ êž°ë¥ì ëì í ì ììµëë€.
-> ìŽê±Ž, ëë€ ííìë ê·žë° ê±° ìëìŒ? í ì ìë€. ê·Œë° ë©ìë ì°žì¡°ë ëë€ë¥Œ ê°ë ì± ìê² ì¬ì©íë €ë ê±°ëê¹ ëìŽê°ì£ŒìŒ
- íšìí íë¡ê·žëë° ì§ì: ë©ìë ì°žì¡°ë íšìí íë¡ê·žëë°ì íµì¬ êž°ë¥ ì€ íëì ëë€. ê²°êµ ëë€ì ì¢ì ì ìŽ ë©ìë ì°žì¡°ì ì¥ì 곌 ê²¹ì¹ë€. ã ë©ìë ì°žì¡°ë ìŽë¬í íšìí ì€íìŒì ìœê² ííí ì ìëë¡ ëìì€ë€.
- 컎íìŒë¬ ìµì í: ìŒë¶ 겜ì°(êŒ ê·žë° ê±Ž ìë!!)ìë ë©ìë 찞조륌 ì¬ì©íë©Ž 컎íìŒë¬ê° ë íšìšì ìž ìœë륌 ìì±í ì ììµëë€. ìŽë ì±ë¥ì í¥ìíë ë° ëììŽ ë ì ìë€ê³ íë€. ì€ìŽ 짧ìì žì ê·žë ë€ë ìêž°ë ìê³ ...
묎íŒ, ê°ê²°í 묞ë²ê³Œ ëì ê°ë ì±ìŒë¡ ìžíŽ ë©ìë ì°žì¡°ë Java 8ìì ëì ë íšìí íë¡ê·žëë° êž°ë¥ ì€ íëë¡ ë§ìŽ ì°ìžë€ê³ íë€.
ì€ìí ê²ì ê°ë ì±ìŽ ì¢ìì§ë€ë ê±°-!
1. ë©ìë ì°žì¡° ë§ëë ë°©ë²
3ê°ì§ ë°©ë²ìŽ ìì.
1) ì ì ë©ìë ì°žì¡° (Static Method Reference)
íŽëì€ìŽëŠ::ì ì ë©ìëë¡ íí
ì륌 ë€ìŽ, Math íŽëì€ì ì ì ë©ìëìž abs륌 ì°žì¡°íë 겜ì°: Math::abs ê°ì~
2) ë€ìí íìì ìžì€íŽì€ ë©ìë ì°žì¡°
ì°žì¡°ë³ì::ìžì€íŽì€ë©ìëë¡ íí
ì륌 ë€ìŽ, 묞ììŽì length ë©ìë륌 ì°žì¡°íë 겜ì°: String::length
3) êž°ì¡Ž ê°ì²Žì ìžì€íŽì€ ë©ìë ì°žì¡°
ê°ì²Žì°žì¡°::ìžì€íŽì€ë©ìëë¡ ííí©ëë€.
ì륌 ë€ìŽ, í¹ì ê°ì²Žì ë©ìë륌 ì°žì¡°íë 겜ì°: object::instanceMethod
3ê°ì§ ë°©ë²ìŒë¡ ìì±íŽ 볎멎 ìŽë ê² ìž ì ìëŽ.
class StringConcatenator {
public void concatenate(String word) {
System.out.print(word + " ");
}
}
@Test
@DisplayName("ë©ìë ì°žì¡°")
void staticMethodTest() {
// 1. ì ì ë©ìë ì°žì¡°
List<String> singer = Arrays.asList("ììŽì ", "ë ë벚벳", "QWER");
singer.forEach(System.out::println); // System.outìŽëŒë íŽëì€ì ì ì ë©ìë println ì°žì¡°
// 2. ë€ìí íìì ìžì€íŽì€ ë©ìë ì°žì¡°
singer.sort(String::compareToIgnoreCase); // String íŽëì€ì ìžì€íŽì€ ë©ìë compareToIgnoreCase ì°žì¡°
// 3. êž°ì¡Ž ê°ì²Žì ìžì€íŽì€ ë©ìë ì°žì¡°
StringConcatenator concatenator = new StringConcatenator();
singer.forEach(concatenator::concatenate); // StringConcatenator ê°ì²Žì ìžì€íŽì€ ë©ìë concatenate ì°žì¡°
}
컎íìŒë¬ë ëë€ ííì ê²ì¬íë ë°©ì곌 ë¹ì·íê², ë©ìë ì°žì¡°ê° íšìí ìží°íìŽì€ì ížíëëì§ íìžíë€.
2. ìì±ì ì°žì¡°
ëŽê° ì ìŒ ìŒë¥ž ìœë 늬í©í ë§ íŽë³Žê³ ì¶ë€ê³ ìê°í ë¶ë¶..
ììì 뎀ë íšìí ìží°íìŽì€ êž°ìµëëê°?
ìê·žëì²ê° ê°ì íšìí ìží°íìŽì€ë¥Œ ì¬ì©íŽì ìì±ì륌 ë§ë€ ì ìë€.
@Test
@DisplayName("ìì±ì ì°žì¡°")
void constructorReference() {
// ëë€ ííììŒë¡ Apple ê°ì²Ž ìì±ì ë§ë€êž°
Supplier<Apple> appleSupplier1 = () -> new Apple();
// ìì±ì ì°žì¡°ë¡ ìŽë ê² ì¬ì©í ì ìë€
Supplier<Apple> appleSupplier2 = Apple::new;
// Supplierì getìŒë¡ ê°ì²Ž ë§ë€ ìë ìë€
Apple apple = appleSupplier2.get();
BiFunction<Color, Integer, Apple> biFunction = Apple::new;
Apple apple1 = biFunction.apply(Color.RED, 20);
}
ìžì€íŽì€ííì§ ìê³ ë ìì±ìë¡ ê°ì²Žë¥Œ ë§ë€ ì ìë€.
7. ëë€, ë©ìë ì°žì¡° íì©íêž°
1 ëšê³) sort ë©ìëì ì ë ¬ ì ëµ ì ë¬íêž°
void sort(Comparator<? super E> c)
sort íšìì ìê·žëì²ë ìŽë ê² ì게ë€.
public class AppleComparator implements Comparator<Apple> {
@Override
public int compare(Apple o1, Apple o2) {
return o1.getWeight() > o2.getWeight() ? o1.getWeight() : o2.getWeight();
}
}
@Test
@DisplayName("sort ì ëµ ì ë¬íêž°")
void sortTest() {
List<Apple> appleList = new ArrayList<>();
appleList.sort(new AppleComparator());
}
sort ëìì íëŒë¯ží° íí ìì ìŽë€. ìŽë ê² Comparator ê°ì²Žë¡ ì ëµì ì ë¬íë©Ž ë€ìí ì ëµì ì ë¬í ì ìë€.
2 ëšê³) ìµëª íŽëì€ ì¬ì©
ë§ìœ ì ìœëì Comparator íŽëì€ë¥Œ í ë²ë§ ì¬ì©íë€ë©Ž íŽëì€ë¡ 구ííë ê²ë³Žë€ë ìµëª íŽëì€ë¡ ìì±íë©Ž ê°ëšíë€.
@Test
@DisplayName("ìµëª
íŽëì€ë¡ 구ííêž°")
void anonymousClassTest() {
List<Apple> appleList = new ArrayList<>();
//appleList.sort(new AppleComparator());
appleList.sort(new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return o1.getWeight() > o2.getWeight() ? o1.getWeight() : o2.getWeight();
}
});
}
3ëšê³) ëë€ ííì ì¬ì©íêž°
ìœë륌 ë€ìŽìŽížììŒë³Žì.
Comparator íšìì ëì€í¬ëŠœí°ë? (T,T) -> int
ê·žë¬ë©Ž Apple Comparator íšì ëì€í¬ëŠœí°ë? (Apple, Apple) -> int
@Test
@DisplayName("ëë€ë¡ 구ííêž°")
void lamdaTest() {
List<Apple> appleList = new ArrayList<>();
// ëë€ ííì ì¬ì©íë©Ž ìŽë ê²!
appleList.sort((Apple o1, Apple o2) -> o1.getWeight() > o2.getWeight() ? o1.getWeight() : o2.getWeight());
// ìë° ì»ŽíìŒë¬ë ëë€ ííìì 컚í
ì€ížë¥Œ ë³Žê³ , íëŒë¯ží° íìì ì¶ë¡ í ì ìë€.
appleList.sort((o1, o2) -> o1.getWeight() > o2.getWeight() ? o1.getWeight() : o2.getWeight());
}
ë ê°ë ì±ì í¥ìíêž° ìíŽì Comparator ê°ì²Žì comparing ë©ìë륌 ì¬ì©í ì ìë€.
Comparatorë ê°ì²Žë¡ ë§ëë Function íšì륌 ìžìë¡ ë°ë ì ì ë©ìëìž comparingì í¬íšíê³ ìë€.
static <T,U extends Comparable<? super U>>
Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)
íì
Tìì ë¹êµ ê°ë¥í ì ë ¬ í€ë¥Œ ì¶ì¶íë íšì륌 ë°ì, íŽë¹ ì ë ¬ í€ë¡ ê°ì²Ž T륌 ë¹êµíë Comparator<T>륌 ë°ííŽ ì€ë€.
@Test
@DisplayName("ëë€ë¡ 구ííêž°")
void lamda2Test() {
List<Apple> appleList = new ArrayList<>();
Comparator<Apple> comparator = Comparator.comparing((Apple apple)-> apple.getWeight());
appleList.sort(Comparator.comparing(apple -> apple.getWeight()));
}
ê·žëì ìë ê² ë°ê¿ì€ ì ìë€.
4ëšê³) ë©ìë ì°žì¡° ì¬ì©íêž°
ë§ì§ë§ ëšê³ë ë©ìë ì°žì¡°ë¡ ë°ê¿ë³Žì.
@Test
@DisplayName("ë©ìë ì°žì¡°ë¡ êµ¬ííêž°")
void methodTest() {
List<Apple> appleList = new ArrayList<>();
appleList.sort(Comparator.comparing(Apple::getWeight));
}
ììœ
- ëë€ ííìì ìœë륌 ê°ê²°íê² íííêž° ìí ìë° 8ì ì¶ê°ë 묞ë²ìŽë€.
- ëë€ ííìì ìµëª íšìì í ì¢ ë¥ìŽë€. ìŽëŠì ìì§ë§ íëŒë¯ží° 늬ì€íž/ë°ë/ë°í íìì ê°ì§ë€.
- íšìí ìží°íìŽì€ë íëì ì¶ì ë©ìë륌 ê°ì§ë ìží°íìŽì€ë€.
- ëë€ ííì ì ì²Žê° íšìí ìží°íìŽì€ì ìžì€íŽì€ê° ëë€.
'ð Java&Spring > 몚ëìë°ìžì¡ì ' 칎í ê³ ëŠ¬ì ë€ë¥ž êž
[몚ëìë°ìžì¡ì ] Stream ì€ížëŠŒ íì© (4) | 2024.03.26 |
---|---|
[몚ëìë°ìžì¡ì ] Stream ì€ížëŠŒ (6) | 2023.12.17 |
[몚ëìë°ìžì¡ì ] ëì íëŒë¯ží°(Behavior Parameter) (4) | 2023.11.19 |