ํ์ค API์ ํจ์ํ ์ธํฐํ์ด์ค
- ์๋ฐ์์ ์ ๊ณตํ๋ ํ์ค API์์ ํ ๊ฐ์ ์ถ์ ๋ฉ์๋๋ฅผ ๊ฐ์ง๋ ์ธํฐํ์ด์ค๋ค์ ๋ชจ๋ ๋๋ค์์ ์ด์ฉ ๊ฐ๋ฅ
- ๋น๋ฒํ๊ฒ ์ฌ์ฉ๋๋ ํจ์ํ ์ธํฐํ์ด์ค๋ java.util.funtion ํ์ค API ํจํค์ง๋ก ์ ๊ณต
- JavaDoc
| ์ข ๋ฅ | ์ถ์ ๋ฉ์๋์ ํน์ง |
|---|---|
| Consumer | ๋งค๊ฐ๊ฐ์ ์๊ณ , ๋ฆฌํด๊ฐ์ ์์ |
| Supplier | ๋งค๊ฐ๊ฐ์ ์๊ณ , ๋ฆฌํด๊ฐ์ ์์ |
| Function |
๋งค๊ฐ๊ฐ๋ ์๊ณ , ๋ฆฌํด๊ฐ๋ ์์ ์ฃผ๋ก ๋งค๊ฐ๊ฐ์ ๋ฆฌํด๊ฐ์ผ๋ก ๋งคํ(ํ์ ๋ณํ) |
| Operator |
๋งค๊ฐ๊ฐ๋ ์๊ณ , ๋ฆฌํด๊ฐ๋ ์์ ์ฃผ๋ก ๋งค๊ฐ๊ฐ์ ์ฐ์ฐํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํด |
| Predicate |
๋งค๊ฐ๊ฐ๋ ์๊ณ , ๋ฆฌํดํ์ ์ boolean ๋งค๊ฐ๊ฐ์ ์กฐ์ฌํ๊ณ true/false๋ฅผ ๋ฆฌํด |
Consumer
- ๋ฆฌํด๊ฐ์ด ์๋ accept() ๋ฉ์๋๋ง ์กด์ฌ
- ๋งค๊ฐ๊ฐ์ ์ฌ์ฉํ ๋ฟ ๋ฆฌํด์ด ์์: ์๋น๋ผ๊ณ ํํํ๊ธฐ๋ ํจ
- Consumer<T>, BiConsumer<T, U>, DoubleConsumer, IntConsumer, LongConsumer, ObjDoubleConsumer<T>, ObjIntConsumer<T>, ObjLongConsumer<T> ๊ฐ ์์
public class Example {
public static void main(String[] args) {
Consumer<String> consumer = t -> System.out.println(t);
consumer.accept("test");
BiConsumer<String, String> biConsumer = (t, u) -> System.out.println(t + u);
biConsumer.accept("te", "st");
DoubleConsumer doubleConsumer = d -> System.out.println(d);
doubleConsumer(3.2);
ObjIntConsumer<String> objIntConsumer = (t, i) -> System.out.println(t + i);
objIntConsumer("test", 1);
}
}
Supplier
- ๋งค๊ฐ ๋ณ์๊ฐ ์๊ณ ๋ฆฌํด๊ฐ์ด ์๋ getXXX() ๋ฉ์๋๊ฐ ์กด์ฌ
- Supplier<div>, BooleanSupplier, DoubleSupplier, IntSupplier, LongSupplier ๊ฐ ์์
public class Example {
public static void main(String[] args) {
IntSupplier intSupplier = () -> {
return (int) (Math.random * 100) + 1;
};
System.out.println(intSupplier.getAsInt());
}
}
Function
- ๋งค๊ฐ๊ฐ๊ณผ ๋ฆฌํด๊ฐ์ด ์๋ applyXXX() ๋ฉ์๋๊ฐ ์กด์ฌ
- ๋งค๊ฐ๊ฐ์ ๋ฆฌํด๊ฐ์ผ๋ก ๋งคํํ๋ ์ญํ
- Function<T, R>, BiFunction<T, U, R>, DoubleFunction<R>, IntFunction<<R>, IntToDoubleFunction, IntToLongFunction, LongToDoubleFunction, LongToIntFunction, ToDoubleBiFunction<T, U>, ToDoubleFunction<T>, ToIntBiFunction<T, U>, ToIntFunction<T>, ToLongBiFunction<T, U>, ToLongFunction<T> ๊ฐ ์์
public class Member {
private int id;
private String name;
public Member(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() { return id };
public String getName() { return name };
}
public class Example1 {
private static List<Member> members = Arrays.asList(new Member(1, "m1"), new Member(2, "m2"));
public static void printString( Function<Member, String> function ) {
for(Member member : members) {
System.out.println(function.apply(member));
}
}
public static int printInt( ToIntFunction<Member> function ) {
for(Member member : members) {
System.out.println(fuction.applyAsInt(member));
}
}
public static void main(String[] args) {
printString(t -> t.getName());
printInt(t -> t.getId());
}
}
public class Member {
private int id;
private String name;
public Member(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() { return id };
public String getName() { return name };
}
public class Example2 {
private static List<Member> members = Arrays.asList(new Member(1, "m1"), new Member(2, "m2"));
public static int sum(ToIntFunction<Member> function) {
int sum = 0;
for(Member member : members) {
sum += funtion.applyAsInt(member);
}
return sum;
}
public static void main(String[] args) {
printString(t -> t.getId());
}
}
Operator
- ๋งค๊ฐ๊ฐ๊ณผ ๋ฆฌํด๊ฐ์ด ์๋ applyXXX() ๋ฉ์๋๊ฐ ์กด์ฌ
- ๋งค๊ฐ๊ฐ์ ์ด์ฉํด ์ฐ์ฐ์ ์ํํ ํ, ๋์ผํ ํ์ ์ผ๋ก ๋ฆฌํด
- BinaryOperator<T>, UnaryOperator<T>, DoubleBinaryOperator, DoubleUnaryOperator, IntBinaryOperator, IntUnaryOperator, LongBinaryOperator, LongUnaryOperator ๊ฐ ์์
public class Example {
private static int[] list = { 10, 20, 30 };
public static int maxOrMin( IntBinaryOperator operator ) {
int result = list[0];
for(int i : list) {
result = operator.applyAsInt(result, i);
}
return result;
}
public static void main(String[] args) {
System.out.println(maxOrMin((a, b) -> Math.max(a, b)));
System.out.println(maxOrMin((a, b) -> Math.min(a, b)));
}
}
Predicate
- ๋งค๊ฐ๊ฐ๊ณผ boolean ๋ฆฌํด๊ฐ์ด ์๋ testXXX() ๋ฉ์๋๊ฐ ์กด์ฌ
- ๋งค๊ฐ๊ฐ์ ์กฐ์ฌํด true/false ๋ฆฌํด
- Predicate<T>, BiPredicate<T, U>, DoublePredicate, IntPredicate, LongPredicate ๊ฐ ์์
public class Member {
private String name;
private int score;
private String gender;
public Member(String name, int score, String gender) {
this.name = name;
this.score = score;
this.gender = gender;
}
public String getName() {
return name;
}
public int score() {
return score
}
public String getGender() {
return gender;
}
}
public class Example {
private static List<Member> members = Arrays.asList(
new Member("m1", 20, "male"),
new Member("m2", 16, "female"),
new Member("m3", 47, "male"),
new Member("m4", 61, "female")
);
public static double avg( Predicate<Membber> predicate) {
int count = 0, sum = 0;
for(Member member : members) {
if(predicate.test(member)) {
++count;
sum += member.getScore();
}
}
return (double) sum / count;
}
public static void main(String[] args) {
System.out.println(avg(t -> t.getGender().eqauls("male")));
System.out.println(avg(t -> t.getGender().eqauls("female")));
}
}
andThen()๊ณผ compose() ๋ํดํธ ๋ฉ์๋
- ๋ํดํธ ๋ฐ static ๋ฉ์๋๋ ์ถ์ ๋ฉ์๋๊ฐ ์๋
- ํจ์ํ ์ธํฐํ์ด์ค์ ์ ์ธ๋์ด๋ ํจ์ํ ์ธํฐํ์ด์ค์ ์ฑ์ง์ ์ ์งํจ
- andThen๊ณผ compose๋ ๋ ๊ฐ์ ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ์์ฐจ์ ์ผ๋ก ์ฐ๊ฒฐ
- ์ฒซ ๋ฒ์งธ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ ๋ฒ์งธ ๋งค๊ฐ๊ฐ์ผ๋ก ์ ๊ณตํด ์ต์ข ๊ฒฐ๊ณผ๊ฐ์ ์ป์
- andThen๊ณผ compose์ ์ฐจ์ด์ ์ ์ด๋ค ํจ์ํ ์ธํฐํ์ด์ค๋ถํฐ ์ฒ๋ฆฌํ๋๋
InterfaceAB interfaceAB = interfaceA.andThen(interfaceB);
intrefaceAB.method();

- andThen์ ๊ฒฝ์ฐ interfaceAB์ method๋ฅผ ํธ์ถํ๋ฉด
- interfaceA๋ฅผ ์ฒ๋ฆฌํ๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ interfaceB์ ๋งค๊ฐ๊ฐ์ผ๋ก ์ ๊ณต
- interfaceB์์ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํด
InterfaceAB interfaceAB = interfaceA.compose(interfaceB);
intrefaceAB.method();

- compose์ ๊ฒฝ์ฐ interfaceAB์ method๋ฅผ ํธ์ถํ๋ฉด
- interfaceB๋ฅผ ์ฒ๋ฆฌํ๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ interfaceA์ ๋งค๊ฐ๊ฐ์ผ๋ก ์ ๊ณต
- interfaceA์์ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํด
Consumer์ ์์ฐจ์ ์ฐ๊ฒฐ
- Consumer๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํดํ์ง ์์
- andThen()์ ํจ์ํ ์ธํฐํ์ด์ค์ ํธ์ถ ์์๋ง ์ ํจ
public class Member {
private int id;
private String name;
private Address address;
public Member(int id, String name, Address address) {
this.id = id;
this.name = name;
this.address = address;
}
public int getId() { return id; }
public String getName() { return name; }
public Address getAddress() { return addresss };
}
public class Address {
private String country;
private String city;
public Address(String country, String) {
this.country = country;
this.city = city;
}
public String getCountry() { return country; }
public String getCity() { return city; }
}
public class Example {
public static void main(String[] args) {
Consumer<Member> consumerA = m -> System.out.println(m.getName());
Consumer<Member> consumerB = m -> System.out.println(m.getId());
Consumer<Member> consumerAB = consumerA.andThen(consumerB);
consumerAB.accept(new Member(1, "member", null));
}
}
Function์ ์์ฐจ์ ์ฐ๊ฒฐ
- Function๊ณผ Operator ์ข ๋ฅ์ ํจ์ํ ์ธํฐํ์ด์ค๋ ๋จผ์ ์คํํ ํจ์ํ ์ธํฐํ์ด์ค์ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ํจ์ํ ์ธํฐํ์ด์ค์ ๋งค๊ฐ๊ฐ์ผ๋ก ๋๊ฒจ์ค
public class Example {
public static void main(String[] args) {
Function<Member, Address> functionA;
Function<Address, String> functionB;
Function<Member, String> functionAB;
functionA = m -> m.getAddress();
functionB = a -> a.getCity();
functionAB = functionA.andThen(functionB);
System.out.println(functionAB.apply(new Member(1, "member", new Address("korea", "seoul"))));
functionAB = functionB.compose(functionA);
System.out.println(functionAB.apply(new Member(1, "member", new Address("korea", "seoul"))));
}
}
and(), or(), negate() ๋ํดํธ ๋ฉ์๋์ isEqual() static ๋ฉ์๋
- Predicate ์ข
๋ฅ์ ํจ์ํ ์ธํฐํ์ด์ค๋ and(), or(), negate() ๋ํดํธ ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์์
- ๋ ผ๋ฆฌ์ฐ์ฐ์ &&, ||, ! ๊ณผ ๋์
public class Example {
public static void main(String[] args) {
IntPredicate predicateA = a -> a & 2 == 0;
IntPredicate predicateB = b -> b & 3 == 0;
IntPredicate predicateAB;
predicateAB = predicateA.and(predicateB);
System.out.println(predicateAB.test(9));
predicateAB = predicateA.or(predicateB);
System.out.println(predicateAB.test(9));
predicateAB = predicateA.negate();
System.out.println(predicateAB.test(9));
}
}
Predicate<T>๋ isEqual() static ๋ฉ์๋๋ ์ ๊ณต
- test() ๋งค๊ฐ๊ฐ์ธ sourceObject์ isEqual()์ ๋งค๊ฐ๊ฐ์ธ targetObject๋ฅผ java.util.Objects ํด๋์ค์ equals()์ ๋งค๊ฐ๊ฐ์ผ๋ก ์ ๊ณต
- Objects.equals(sourceObject, targetObject)์ ๋ฆฌํด๊ฐ์ ์ป์ด ์๋ก์ด Predicate<T>๋ฅผ ์์ฑ
public class Example { Predicate<String> predicate; predicate = Predicate.isEqual(null); System.out.println(predicate.test(null)); // true predicate = Predicate.isEqual("test"); System.out.println(predicate.test(null)); // false predicate = Predicate.isEqual(null); System.out.println(predicate.test("test")); // false predicate = Predicate.isEqual("test"); System.out.println(predicate.test("test")); // true predicate = Predicate.isEqual("not test"); System.out.println(predicate.test("test")); // false }minBy(), maxBy() static ๋ฉ์๋
- BinaryOperator<T> ํจ์ํ ์ธํฐํ์ด์ค๋ minBy(), maxBy() static ๋ฉ์๋ ์ ๊ณต
- ๋งค๊ฐ๊ฐ์ผ๋ก ์ ๊ณต๋๋ Comparator๋ฅผ ์ด์ฉํด์ ์ต๋, ์ต์ T๋ฅผ ์ป๋ BinaryOperator<T>๋ฅผ ์ ๊ณต
public class Item { private String name; private int price; public Item(String name, int price) { this.name = name; this.price = price; } public String getName() { return name; } public int getPrice() { return price; } } public class Example { public static void main(String[] args) { BinaryOperator<Item> binaryOperator; binaryOperator = BinaryOperator.minBy((i1, i2) -> Integer.compare(i1.price, i2.price)); System.out.println(binaryOperator.apply(new Item("i1", 100), new Item("i2", 200)).getPrice()); binaryOperator = BinaryOperator.maxBy((i1, i2) -> Integer.compare(i1.price, i2.price)); System.out.println(binaryOperator.apply(new Item("i1", 100), new Item("i2", 200)).getPrice()); } }
๋ฉ์๋ ์ฐธ์กฐ(Method Reference)
- ๋ฉ์๋๋ฅผ ์ฐธ์กฐํด ๋งค๊ฐ ๋ณ์์ ์ ๋ณด ๋ฐ ๋ฆฌํด ํ์ ์ ์์๋ด์ด, ๋๋ค์์ ๋ถํ์ํ ๋งค๊ฐ ๋ณ์๋ฅผ ์ ๊ฑฐํ ์ ์์
์์
- ๋ ๊ฐ์ ์๋ฅผ ๋ฐ์ ํฐ ์๋ฅผ ๋ฐํํ๋ ๋๋ค์์ ๊ฒฝ์ฐ, ๋จ์ํ ๋ ๊ฐ์ ๊ฐ์ ๋ฐ์ Math.max()์ ์ ๋ฌํ๋ ์ญํ
- ์ฐธ์กฐ๋ฅผ ํ์ฉํด ๊ฐ์ ํ ์ ์์
- ๋ฉ์๋ ์ฐธ์กฐ๋ ์ธํฐํ์ด์ค์ ์ต๋ช
๊ตฌํ ๊ฐ์ฒด๋ก ์์ฑ
- ํ๊ฒ ํ์ ์ธ ์ธํฐํ์ด์ค์ ์ถ์ ๋ฉ์๋๊ฐ ์ด๋ค ๋งค๊ฐ ๋ณ์๋ฅผ ๊ฐ์ง๊ณ ๋ฆฌํด ํ์ ์ด ๋ฌด์์ธ๊ฐ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง
(n1, n2) -> Math.max(n1, n2);
// ์์ ๊ฐ์
Math::max
// IntBinaryOperator ๋ ๋ ๊ฐ์ int ๊ฐ์ ๋ฐ์ int๋ฅผ ๋ฆฌํดํ๋ฏ๋ก Math::max ๋ฉ์๋ ์ฐธ์กฐ ๋์
๊ฐ๋ฅ
IntBinaryOperator operator = (n1, n2) -> Math.max(n1, n2);
IntBinaryOperator operator = Math::max // ์์ ๊ฐ์
static ๋ฉ์๋์ ์ธ์คํด์ค ๋ฉ์๋ ์ฐธ์กฐ
- static ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ ๊ฒฝ์ฐ, ํด๋์ค ์ด๋ฆ ๋ค์ :: ๊ธฐํธ๋ฅผ ๋ถ์ด๊ณ static ๋ฉ์๋ ์ด๋ฆ์ ์ ์
- ์ธ์คํด์ค ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ ๊ฒฝ์ฐ, ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ค์ ์ฐธ์กฐ ๋ณ์ ๋ค์ :: ๊ธฐํธ๋ฅผ ๋ถ์ด๊ณ ์ธ์คํด์ค ๋ฉ์๋ ์ด๋ฆ์ ๊ธฐ์
public class Calculator {
public static int sum(int x, int y) {
return x + y;
}
public int multiply(int x, int y) {
return x * y;
}
}
public class Example {
public static void main(String[] args) {
IntBinaryOperator operator;
operator = (x, y) -> Calculrator.sum(x, y);
System.out.println(operator.applyAsInt(2, 4));
operator = Calculator::sum;
System.out.println(operator.applyAsInt(3, 4));
Calculator calculator = new Calculator();
operator = (x, y) -> calculator.multiply(x, y);
System.out.println(operator.applyAsInt(2, 4));
operator = calculator::multiply;
System.out.println(operator.applyAsInt(2, 4));
}
}
๋งค๊ฐ ๋ณ์์ ๋ฉ์๋ ์ฐธ์กฐ
- a ๋งค๊ฐ ๋ณ์์ ๋ฉ์๋๋ฅผ ํธ์ถํด b๋ฅผ ๋ฉ์๋์ ์ธ์๋ก ๋๊ฒจ์ฃผ๋ ๊ฒฝ์ฐ
- a์ ํด๋์ค ์ด๋ฆ ๋ค์ :: ๊ธฐํธ๋ฅผ ๋ถ์ด๊ณ ๋ฉ์๋ ์ด๋ฆ์ ๊ธฐ์
public class Example {
public static void main(String[] args) {
ToIntBinaryFunction<String, String> function;
function = (a, b) -> a.compareToIgnoreCase(b);
System.out.println(function.applyAsInt("test", "TEST")); // 0
function = String::compareToIgnoreCase;
System.out.println(function.applyAsInt("test", "TEST")); // 0
}
}
์์ฑ์ ์ฐธ์กฐ
- ๋ฉ์๋ ์ฐธ์กฐ์๋ ์์ฑ์ ์ฐธ์กฐ๋ ํฌํจ๋จ
- ํด๋์ค ์ด๋ฆ ๋ค์ :: ๊ธฐํธ๋ฅผ ๋ถ์ด๊ณ new ์ฐ์ฐ์๋ฅผ ๊ธฐ์
- ์์ฑ์๊ฐ ์ค๋ฒ๋ก๋ฉ๋์ด ์ฌ๋ฌ ๊ฐ ์์ ๊ฒฝ์ฐ, ์ปดํ์ผ๋ฌ๋ ํจ์ํ ์ธํฐํ์ด์ค์ ์ถ์ ๋ฉ์๋์ ๋์ผํ ๋งค๊ฐ ๋ณ์ ํ์
๊ณผ ๊ฐ์๋ฅผ ๊ฐ์ง๊ณ ์๋ ์์ฑ์๋ฅผ ์ฐพ์ ์คํ
- ์์ผ๋ฉด, ์ปดํ์ผ ์ค๋ฅ
public class Member {
private String id;
private String name;
public Member() {
System.out.println("Member()");
}
public Member(String id) {
System.out.println("Member(String)");
this.id = id;
}
public Member(String id, String name) {
System.out.println("Member(String, String)");
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
}
public class Example {
public static void main(String[] args) {
Function<String, Member> function1 = Member::new;
Member member1 = function1.apply("m1");
BiFunction<String, String, Member> function2 = Member::new;
Member member2 = function2.apply("m2", "test");
}
}