Epilogue๐โโ๏ธ
๋์ค์ ๊ณต๋ถํด์ผ์ง ํ๊ณ ๋ฏธ๋ฃจ๊ณ ๊ทธ๋ฅ ๊ตฌ๊ธ๋ง๋งํด์ ๊ทธ ๋ ๊ทธ ๋ ์ฌ์ฉํ์๋๋ฐ,๋ฆ์์ง๋ง ์ง๊ธ์ด๋ผ๋ ์ ๋๋ก ์๊ณ ์ฌ์ฉํ์ ์๊ฐ์ด ๋ค์ด ์ ๋ฆฌ๋ฅผ ์์ํด๋ด
๋๋ค!!
๋๋ค์์ ์ต๋ช ํจ์๋ฅผ ์์ฑํ๊ธฐ ์ํ ์์ผ๋ก ๊ฐ์ฒด์งํฅ์ธ์ด๋ณด๋ค๋ ํจ์์งํฅ์ธ์ด์ ๊ฐ๊น๋ค. (java8๋ถํฐ ์ง์)
์ฝ๋๊ฐ ๋งค์ฐ ๊ฐ๊ฒฐํด์ง๊ณ , ์ปฌ๋ ์ ์ ์์๋ฅผ ํํฐ๋งํ๊ฑฐ๋ ๋งคํํ์ฌ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค๋ ์ฅ์
๋๋ค์์ ํํ๋ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ์ฝ๋ ๋ธ๋ก์ด์ง๋ง, ๋ฐํ์ ์์๋ ์ต๋ช ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
- ๋๋ค์ -> ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ์ฝ๋ ๋ธ๋ก -> ์ต๋ช ๊ตฌํ ๊ฐ์ฒด
Runnable runnable = new Runnable() { // ์ต๋ช
๊ตฌํ ๊ฐ์ฒด
public void method();
};
// ๋๋ค์ ํํ
Runnable runnable = (ํ์
๋งค๊ฐ๋ณ์, ...) -> {์คํ๋ฌธ; ...};
๋ชจ๋ ์ธํฐํ์ด์ค๋ฅผ ๋๋ค์์ ํ์ผํ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๊ณ , ๋๋ค์์ด ํ๋์ ๋ฉ์๋๋ฅผ ์ ์ํ๊ธฐ ๋๋ฌธ์ ๋ ๊ฐ ์ด์์ ์ถ์ ๋ฉ์๋๊ฐ ์ ์ธ๋ ์ธํฐํ์ด์ค๋ ๋๋ค์์ ์ด์ฉํด์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๋ค.
ํ๋์ ์ถ์ ๋ฉ์๋๊ฐ ์ ์ธ ๋ ์ธํฐํ์ด์ค๋ง์ด ๋๋ค์์ ํ๊ฒํ์ ์ด ๋ ์ ์๋ค. = ํจ์์ ์ธํฐํ์ด์ค
์ด๊ฒ์ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ ์ด๋ ธํ ์ด์ ์ด @FunctionalInterface์ด๋ค.
๋๋ค์ ํํ์ ์ํ MyFunctionalInterface Class
@FunctionalInterface
public Interface MyFunctionalInterface{
// (โป์ฃผ์) ๋ฉ์๋๋ ๋ฌด์กฐ๊ฑด ํ๋๋ง ์ ์ธ์ด ๊ฐ๋ฅํ๋, ์ค๋ช
์ ์ํด ์ฌ๋ฌ๊ฐ๋ฅผ ์ ์ธํ ๊ฒ์
public void method(); // 1.๋งค๊ฐ๋ณ์X , ๋ฆฌํด๊ฐX
public void method(int a); // 2.๋งค๊ฐ๋ณ์O , ๋ฆฌํด๊ฐX
public int method(int a, int b); // 3.๋งค๊ฐ๋ณ์O , ๋ฆฌํด๊ฐO
}
์คํ๋ฌธ
public class MyFunctionalInterfaceExample{
public static void main(String[] args){
// 1.๋งค๊ฐ๋ณ์X , ๋ฆฌํด๊ฐX
MyFunctionalInterface fi = () -> System.out.println("test");
fi.method(); // test
// 2.๋งค๊ฐ๋ณ์O , ๋ฆฌํด๊ฐX
MyFunctionalInterface fi2 = (a) -> System.out.println(a+2);
fi2.method(5); // 7
// 3.๋งค๊ฐ๋ณ์O , ๋ฆฌํด๊ฐO
MyFunctionalInterface fi3 = (a, b) -> {return a+b};
fi2.method(fi3.method(5,7)); // 12
}
}
๋๋ค์์ ์คํ ๋ธ๋ก์๋ ํด๋์ค์ ๋ฉค๋ฒ ๋ฐ ๋ก์ปฌ ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
ํด๋์ค์ ๋ฉค๋ฒ๋ ์ ์ฝ ์ฌํญ ์์ด ์ฌ์ฉ ๊ฐ๋ฅํ์ง๋ง, ๋ก์ปฌ ๋ณ์๋ ์ ์ฝ์ฌํญ์ด ๋ฐ๋ฅธ๋ค.
โthis ํค์๋ ์ฌ์ฉ์ ์ฃผ์ ํ์
public class UsingThis {
public int outterField = 10;
class Inner{
int innerField = 20;
void method(){
MyFunctionalInterface fi = () -> {
System.out.println("outterField :: " + outterField);
// ๋ฐ๊นฅ๊ฐ์ฒด์ ์ฐธ๊ณ ๋ฅผ ์ป๊ธฐ ์ํด์๋ ํด๋์ค๋ช
.this
System.out.println("outterField :: " + UsingThis.this.outterField);
System.out.println("innerField :: " + innerField);
// ๋๋ค์ ๋ด๋ถ์์์ this๋ ์ค์ฒฉ๊ฐ์ฒด์ธ Inner๋ฅผ ์ฐธ์กฐ
System.out.println("innerField :: " + this.innerField);
};
fi.method();
}
}
public static void main(String... args){
UsingThis usingThis = new UsingThis();
UsingThis.Inner inner = usingThis.new Inner();
inner.method();
}
}
โ๋ก์ปฌ ๋ณ์ ์ฌ์ฉ
public class UsingLocalVariable {
void method(int arg){ // arg๋ finalํน์ฑ์ ๊ฐ์ง
int localVar = 40; // localVar๋ final์ ํน์ฑ์ ๊ฐ์ง
// arg = 31; // final ํน์ฑ๋๋ฌธ์ ์์ ๋ถ๊ฐ, ์ปดํ์ผ ์ค๋ฅ ๋ฐ์
// localVar = 30; // final ํน์ฑ๋๋ฌธ์ ์์ ๋ถ๊ฐ, ์ปดํ์ผ ์ค๋ฅ ๋ฐ์
// lambda
MyFunctionalInterface fi = () -> {
System.out.println("arg : " + arg);
System.out.println("localVar : " + localVar);
};
fi.method();
}
public static void main(String... args){
UsingLocalVariable usingLocalVariable = new UsingLocalVariable();
usingLocalVariable.method(50);
// 50
// 40
}
}
์ข ๋ฅ | ์ถ์๋ฉ์๋ ํน์ง | ๋ฉ์๋ |
---|---|---|
Consumer | ๋งค๊ฐ๊ฐO , ๋ฆฌํด๊ฐX | accept() |
Supplier | ๋งค๊ฐ๊ฐX, ๋ฆฌํด๊ฐO | getXXX() |
Function | ๋งค๊ฐ๊ฐO, ๋ฆฌํด๊ฐO ๋งค๊ฐ๊ฐ์ ๋ฆฌํด๊ฐ์ผ๋ก ๋งคํ(ํ์ ๋ณํ) | applyXXX() |
Operator | ๋งค๊ฐ๊ฐO, ๋ฆฌํด๊ฐO ๋งค๊ฐ๊ฐ์ ์ฐ์ฐํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํด | applyXXX() |
Perdicate | ๋งค๊ฐ๊ฐO, ๋ฆฌํด๊ฐ boolean | testXXX() |
public class ConsumerExample {
public static void main(String[] args){
// ๊ฐ์ฒด t๋ฅผ ๋ฐ์ ์๋น
Consumer<String> consumer = t-> System.out.println("test "+t);
consumer.accept("java");
// ๊ฐ์ฒด x์ y๋ฅผ ๋ฐ์ ์๋น
BiConsumer<String, String> biConsumer = (x,y) ->System.out.println(x+ "::"+ y);
biConsumer.accept("hello", "java");
// double๊ฐ์ ๋ฐ์ ์๋น
DoubleConsumer doubleConsumer = t -> System.out.println("java" + t);
doubleConsumer.accept(0.8);
// ๊ฐ์ฒดa์ int b๊ฐ์ ๋ฐ์ ์๋น accept(T t, int value)
ObjIntConsumer<String> objIntConsumer = (a, b) -> System.out.println(a + b);
objIntConsumer.accept("hello", 8);
}
}
ex) Supplier : T๊ฐ์ฒด๋ฅผ ๋ฆฌํด
โ BooleanSupplier : boolean getAsBoolean()
public class SupplierExample {
public static void main(String[] args){
// ๋งค๊ฐ๋ณ์๋ ์๊ณ , int๊ฐ์ ๋ฆฌํด
IntSupplier intSupplier = () ->{
int num = (int)(Math.random() * 6) +1;
return num;
};
System.out.println("์ฃผ์ฌ์ ๋์ ์ : "+intSupplier.getAsInt());
}
}
(์ฐธ๊ณ ) Student Class : name(String) , englishScore(int), mathScore(int) ๋ณ์ ๊ฐ์ง
public class FunctionExample1 {
private static List<Student> list = Arrays.asList(
new Student("์ฐจ", 100,100),
new Student("๊น", 95 , 80)
);
// Function<T,R> : ๊ฐ์ฒดT๋ฅผ ๊ฐ์ฒดR๋ก ๋งคํ
public static void printString(Function<Student, String> function){
for(Student student : list){
// ๋๋ค์ ์คํ : R apply(T)
System.out.print(function.apply(student) + " ");
}
System.out.println();
}
// ToIntFunction<T t> : ๊ฐ์ฒด T๋ฅผ int๋ก ๋งคํ
public static void printInt(ToIntFunction<Student> function){
for(Student student : list){
// ๋๋ค์ ์คํ : int applyeAsInt(T t)
System.out.print(function.applyAsInt(student)+ " ");
}
System.out.println();
}
public static void main(String... args){
System.out.println("ํ์ ์ด๋ฆ");
printString(t -> t.getName());
System.out.println("์์ด ์ ์");
printInt( t -> t.getEnglishScore());
System.out.println("์ํ ์ ์");
printInt(t -> t.getMathScore());
}
}
Function๊ณผ์ ์ฐจ์ด์ ์ ๋งค๊ฐ๊ฐ์ ๋ฆฌํดํ๋ ์ญํ ๋ณด๋ค๋ ๋งค๊ฐ๊ฐ์ ์ด์ฉํด ์ฐ์ฐ์ํ ํ ๋์ผํ์ ์ผ๋ก ๋ฐํํด์ค๋ค.
public class OperatorExample {
private static int[] scores = {92, 85, 86};
// IntBianryOperator : ๋ ๊ฐ์ int ์ฐ์ฐ
public static int maxOrMin(IntBinaryOperator operator){
int result = scores[0];
for(int score: scores){
// ๋๋ค์ ์คํ : int applyAsInt(int)
result = operator.applyAsInt(result, score);
}
return result;
}
public static void main(String... args){
int max = maxOrMin(
(a,b) -> {
if(a >= b) return a;
else return b;
}
);
System.out.println("์ต๋๊ฐ : "+max);
int min = maxOrMin(
(a,b) -> {
if(a <= b) return a;
else return b;
}
);
System.out.println("์ต์๊ฐ : "+min);
}
}
public class PredicateExample {
private static List<Student> list = Arrays.asList(
new Student("์ฐจ์ฐจ์ฐจ", "์ฌ์", 90),
new Student("Lee", "์ฌ์", 77),
new Student("๊น๊น๊น","๋จ์", 80),
new Student("์ ์ ์ ","๋จ์", 60)
);
// Predicate<T> : ๊ฐ์ฒด T๋ฅผ ์กฐ์ฌ
public static double avg(Predicate<Student> predicate){
int count = 0 ;
int sum = 0;
for(Student student : list){
// boolean test(T t)
if(predicate.test(student)){
count++;
sum += student.getMathScore();
}
}
return (double) sum / count;
}
// ๋จ์, ์ฌ์ ํ๊ท ์ ์ ๊ตฌํ๊ธฐ
public static void main(String... args){
double maleAvg = avg(t-> t.getSex().equals("๋จ์"));
System.out.println("๋จ์ ํ๊ท ์ ์ : "+maleAvg);
double femaleAvg = avg(t-> t.getSex().equals("์ฌ์"));
System.out.println("์ฌ์ ํ๊ท ์ ์ : "+femaleAvg);
}
}
๋ํดํธ ๋ฐ ์ ์ ๋ฉ์๋๋ ์ถ์ ๋ฉ์๋๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ํจ์์ ์ธํฐํ์ด์ค์ ์ ์ธ๋์ด๋ ํจ์์ ์ธํฐํ์ด์ค์ ์ฑ์ง์ ์์ง ์๋๋ค. java.util.functionํจํค์ง์ ํจ์์ ์ธํฐํ์ด์ค๋ ํ๋ ์ด์์ ๋ํดํธ ๋ฐ ์ ์ ๋ฉ์๋๋ฅผ ๊ฐ์ง๋ค.
์ธํฐํ์ด์คAB = ์ธํฐํ์ด์คA.andThen(์ธํฐํ์ด์คB);
์ต์ข ๊ฒฐ๊ณผ = ์ธํฐํ์ด์คAB.method();
์ธํฐํ์ด์คAB์ method()๋ฅผ ํธ์ถํ๋ฉด ์ฐ์ ์ธํฐํ์ด์คA๋ถํฐ ์ฒ๋ฆฌํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์ธํฐํ์ด์คB์ ๋งค๊ฐ๊ฐ์ผ๋ก ์ ๊ณต.
์ธํฐํ์ด์คB๋ ์ ๊ณต๋ฐ์ ๋งค๊ฐ๊ฐ์ ๊ฐ์ง๊ณ ์ฒ๋ฆฌํ ํ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํด.
ex) Consumer, Functon, Operatorํจ์ ๋ํดํธ๋ฉ์๋ ์ ๊ณต
์ธํฐํ์ด์คAB์ method()๋ฅผ ํธ์ถํ๋ฉด ์ฐ์ ์ธํฐํ์ด์คB๋ถํฐ ์ฒ๋ฆฌํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์ธํฐํ์ด์คA์ ๋งค๊ฐ๊ฐ์ผ๋ก ์ ๊ณต
์ธํฐํ์ด์คA๋ ์ ๊ณต๋ฐ์ ๋งค๊ฐ๊ฐ์ ๊ฐ์ง๊ณ ์ฒ๋ฆฌํ ํ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํด
public class FunctionAndThenComposeExample {
public static void main(String[] args){
Function<Member, Address> functionA;
Function<Address, String> functionB;
Function<Member, String> functionAB;
String city;
functionA = (m) -> m.getAddress();
functionB = (m) -> m.getCity();
// andThen() : ์ธํฐํ์ด์คA๋ถํฐ ์ฒ๋ฆฌํ ๋ค ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ธํฐํ์ด์คB๊ฐ ์ฒ๋ฆฌํ ํ ์ต์ข
๊ฒฐ๊ณผ ๋ฆฌํด
functionAB = functionA.andThen(functionB);
city = functionAB.apply(
new Member("ํ๊ธธ๋", "gil", new Address("ํ๊ตญ","์์ธ"))
);
System.out.println("๊ฑฐ์ฃผ ๋์ : "+city);
// compose() : ์ธํฐํ์ด์คB๋ถํฐ ์ฒ๋ฆฌํ ๋ค ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ธํฐํ์ด์คA๊ฐ ์ฒ๋ฆฌํ ํ ์ต์ข
๊ฒฐ๊ณผ ๋ฆฌํด
functionAB = functionB.compose(functionA);
city = functionAB.apply(
new Member("ํ๊ธธ๋", "gil", new Address("ํ๊ตญ","์์ธ"))
);
System.out.println("๊ฑฐ์ฃผ ๋์ : "+city);
}
}
and() : ๋ Predicate๊ฐ ๋ชจ๋ true๋ฅผ ๋ฆฌํดํ๋ฉด ์ต์ข ์ ์ผ๋ก true ๋ฆฌํด
or() : ๋ Predicate ์ค ํ๋๋ง true๋ฅผ ๋ฆฌํดํ๋ฉด ์ต์ข ์ ์ผ๋ก true ๋ฆฌํด
negate() : ์๋ Predicate์ ๊ฒฐ๊ณผ๊ฐ true๋ฉด false๋ฅผ ๋ฆฌํด, false๋ฉด true๋ฅผ ๋ฆฌํด
// 2์ ๋ฐฐ์
IntPredicate predicateA = a -> a % 2 == 0;
// 3์ ๋ฐฐ์
IntPredicate predicateB = b -> b % 3 == 0;
IntPredicate predicateAB;
boolean result;
// and()
predicateAB = predicateA.and(predicateB);
result = predicateAB.test(9);
System.out.println("9๋ 2์ 3์ ๋ฐฐ์์
๋๊น? : "+result);
// or()
predicateAB = predicateA.or(predicateB);
result = predicateAB.test(9);
System.out.println("9๋ 2 ๋๋ 3์ ๋ฐฐ์์
๋๊น? : "+result);
// negate()
predicateAB = predicateA.negate();
result = predicateAB.test(9);
System.out.println("9๋ ํ์์
๋๊น? : "+result);
// isEquals()
Predicate<String> predicate;
predicate = Predicate.isEqual("JAVA8");
System.out.println("JAVA8, null :" +predicate.test(null));
predicate = Predicate.isEqual(null);
System.out.println("null, null :" +predicate.test(null));
o1๊ณผ o2๋ฅผ ๋น๊ตํ์ฌ o1์ด ์์ผ๋ฉด ์์๋ฅผ, o1๊ณผ o2๊ฐ ๋์ผํ๋ฉด 0์ , o1์ด ํฌ๋ฉด ์์๋ฅผ ๋ฆฌํดํ๋ compare()
BinaryOperator<Fruit> binaryOperator;
Fruit fruit;
// compare()
// (o1, o2) -> {return o1> o2 ? (+) : (-)
binaryOperator = BinaryOperator.minBy((o1, o2) -> Integer.compare(o1.price, o2.price));
fruit = binaryOperator.apply(new Fruit("๋ธ๊ธฐ", 2000), new Fruit("์ฌ๊ณผ", 6000));
System.out.println("์ผ ๊ณผ์ผ : "+fruit.name);
binaryOperator = BinaryOperator.maxBy((o1, o2) -> Integer.compare(o1.price, o2.price));
fruit = binaryOperator.apply(new Fruit("๋ธ๊ธฐ", 2000), new Fruit("์ฌ๊ณผ", 6000));
System.out.println("๋น์ผ ๊ณผ์ผ : "+fruit.name);
// ๊ธฐ์กด ๋ฉ์๋ ๋จ์ํธ์ถ
(left, right) -> Math.max(left, rigth);
// ๋ถํ์ํ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๊ฑฐํ์ฌ ๋ฉ์๋ ์ฐธ์กฐ
(left, right) -> Math::max;
- ์ ์ ๋ฉ์๋ ์ฐธ์กฐ > ํด๋์ค :: ๋ฉ์๋ ex)Calculator :: staticMethod;
- ์ธ์คํด์ค ๋ฉ์๋ ์ฐธ์กฐ > ์ฐธ์กฐ๋ณ์ :: ๋ฉ์๋ ex) calculator :: instanceMethod;
public class Calculator {
public static int staticMethod(int x, int y){
return x+y;
}
public int instanceMethod(int x, int y){
return x+y;
}
}
IntBinaryOperator operator;
// ์ ์ ๋ฉ์๋ ํธ์ถ
operator = (x,y) -> Calculator.staticMethod(x,y);
System.out.println(operator.applyAsInt(5,7));
// ์ ์ ๋ฉ์๋ ์ฐธ์กฐ
operator = Calculator :: staticMethod;
System.out.println(operator.applyAsInt(1,2));
// ์ธ์คํด์ค ๋ฉ์๋ ํธ์ถ
Calculator calculator = new Calculator();
operator = (x,y) -> calculator.instanceMethod(x, y);
System.out.println(operator.applyAsInt(5,7));
// ์ธ์คํด์ค ๋ฉ์๋ ์ฐธ์กฐ
operator = calculator ::instanceMethod;
System.out.println(operator.applyAsInt(1,3));
public class Member {
private String name;
private String id;
public Member(String id){
System.out.println("String id ์คํ");
this.id = id;
}
public Member(String name, String id){
System.out.println("String id, String name ์คํ");
this.name = name;
this.id = id;
}
}
// void main ํธ์ถ
Function<String, Member> function1 = Member :: new;
Member member1 = function1.apply("angel1");
BiFunction<String, String, Member> function2 = Member :: new;
Member member2 = function2.apply("name", "angel2");
โป [์ด๊ฒ์ด ์๋ฐ๋ค ์ ์ฉ๊ถJava ํ๋ก๊ทธ๋๋ฐ ์ ๋ณต2] ํด๋น ์ฑ ์ ์ฐธ๊ณ ํ๋ฉฐ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.