자바에서 제공하는 함수형 인터페이스
[java.util.function 패키지]
파라미터 | 리턴 | |
Consumer 계열 | O | X |
Supplier 계열 | X | O |
Function 계열 | O | O |
Operator 계열 | O | O |
Predicate 계열 | O | boolean |
1. Consumer 계열(소비자)
- 파라미터를 받아서 소비한다
- 리턴하지 않음
class Student {
String name;
double score;
public Student(String name, double score) {
super();
this.name = name;
this.score = score;
}
}
// 익명 내부클래스 방식
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String t) {
System.out.println(t);
}
};
consumer.accept("Hello");
System.out.println("----------------------------------");
// 람다식 형태
// Consumer<String> consumer2 =
// (String t) -> { System.out.println(t); };
Consumer<String> consumer2 =
x -> System.out.println(x);
consumer2.accept("Hello2");
System.out.println("-----------------------------------");
Student s1 = new Student("홍길동", 80);
// 람다식 심플하게 표현될 때 주로 사용하므로
// 보통 한줄로 표기 가능할 때 사용됨
// 한줄씩 표현
printStudent(s1, s -> System.out.println(s.name));
printStudent(s1, s -> System.out.println(s.score *= 1.5));
printStudent(s1, s -> System.out.println(s.name + " : " + s.score));
System.out.println("---------------------------------------------");
// 여려줄 표현
printStudent(s1, s -> {
System.out.println(s.name);
s.score *= 1.5;
System.out.println(s.name + " : " + s.score);
});
} // main() 메서드 끝
// 학생을 출력하려고 하는데 방식은 아직 미정.
// 출력방식을 전달 받음(Consumer<Studnent> printer)
public static void printStudent(Student s, Consumer<Student> printer) {
printer.accept(s);
}
2. Supplier 계열(공급자)
- 파라미터를 받지 않는다
- 자체적으로 리턴할 값을 생성한다
// 익명의 내부클래스 방식
// <T>의 값이 return 타입을 결정함
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return "Hello";
}
};
System.out.println(supplier.get());
System.out.println("-------------------------------------");
// 람다식 표현
// Supplier<String> supplier2 =
// () -> { return "Hello"; };
Supplier<String> supplier2 =
() -> "Hello";
// 파라미터 없음 : 소괄호() 생략 불가
// 단순한 리턴문 1개 : 중괄호 {} 생략가능, return 생략 가능
// <T> 의 값이 return 타입을 결정함
System.out.println(supplier2.get());
// PSupplier
// P : Boolean, Integer, Long, Double 을 의미
System.out.println("======= PSupplier ======");
IntSupplier supplier3 = () -> {
Random random = new Random();
return random.nextInt(6) + 1;
};
System.out.println(supplier3.getAsInt());
3. Function 계열
- 파라미터, 리턴 모두 존재
// Person 클래스 정의
class Person {
String name;
int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
class FunctionTest {
Person person;
// String 과 Integer를 매개변수로 받고 Person 을 리턴하는
// BiFunction 타입에 String, Integer를 받는 메서드 apply() 활용
public void addPerson(BiFunction<String, Integer, Person>
function, String name, Integer age) {
person = function.apply(name, age);
}
// String을 파라미터로 받고 String을 리턴하는
// Function 타입에 String 을 받는 apply() 활용
public void printPerson(Function<String, String> function, String name) {
System.out.println(function.apply(name));
}
// String을 파라미터로 받아 int를 리턴하는
// ToIntFunction 타입에 applyAsInt() 활용
public void printAge(ToIntFunction<String> function, String name) {
System.out.println(name + "의 나이 : " + function.applyAsInt(name));
}
}
FunctionTest ft = new FunctionTest();
// 익명 내부클래스로 코딩
ft.addPerson(new BiFunction<String, Integer, Person>() {
@Override
public Person apply(String t, Integer u) {
return new Person(t, u);
}
}, "홍길동", 20);
ft.printPerson(new Function<String, String>() {
@Override
public String apply(String t) {
if(ft.person.name.equals(t)) {
return ft.person.toString();
} else {
return "unKnown user";
}
}
}, "홍길동");
ft.printAge(new ToIntFunction<String>() {
@Override
public int applyAsInt(String value) {
if(ft.person.name.equals(value)) {
return ft.person.age;
} else {
return 0;
}
}
}, "홍길동");
System.out.println("-------------------------------------------");
// 람다식 표현
FunctionTest ft2 = new FunctionTest();
ft2.addPerson((name, age) -> new Person(name, age), "홍길동", 20);
ft2.printPerson(name -> {
if(ft.person.name.equals(name)) {
return ft.person.toString();
} else {
return "unKnown user";
}
}
, "홍길동");
ft2.printAge(name -> {
if(ft.person.name.equals(name)) {
return ft.person.age;
} else {
return 0;
}
}
, "홍길동");
4. Operator 계열
- Function 계열과 유사하게 파라미터와 리턴을 갖는다.
- 차이점은 Operator 계열은 매개변수 타입이 곧 리턴타입이 된다
- 매개변수를 전달받아 "어떠한 연산" 후 같은 타입을 리턴할 때 사용
// <Type T> 인자를 하나 받고 동일한 제너럴 타입의 객체를
// 리턴하는 함수형 인터페이스
UnaryOperator<Double> op1 = x -> Math.pow(x, 2);
UnaryOperator<Double> op2 = new UnaryOperator<Double>() {
@Override
public Double apply(Double t) {
return Math.pow(t, 2);
}
};
System.out.println(op1.apply(10.0));
System.out.println(op2.apply(10.0));
System.out.println("--------------------------");
// Double 타입의 파라미터를 입력받아 Double 타입을 리턴
DoubleBinaryOperator op3 = new DoubleBinaryOperator() {
@Override
public double applyAsDouble(double left, double right) {
return Math.pow(left, right);
}
};
DoubleBinaryOperator op4 = (x, y) -> Math.pow(x, y);
System.out.println(op3.applyAsDouble(100, 2));
System.out.println(op4.applyAsDouble(100, 2));
5. Predicate 계열
- Function, Operator 와 같이 파라미터와 리턴을 갖는다
- 리턴타입이 boolean으로 고정되어 있음
- 매개변수를 전달받아 "어떠한 연산" 후 true/false 리턴할 때 사용
class PredicateTest {
int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
public void printSome(IntPredicate pred) {
for(int num : nums) {
if(pred.test(num)) {
System.out.println(num + "\t");
}
}
}
}
// 익명 객체 활용
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String t) {
return t.contains("Java");
}
};
System.out.println(predicate.test("javaScript"));
System.out.println("------------------------------------");
// 람다식
Predicate<String> predicate2 = name -> name.contains("Java");
System.out.println(predicate2.test("JavaScript"));
System.out.println("===================================");
PredicateTest pt = new PredicateTest();
// 익명 구현 객체
pt.printSome(new IntPredicate() {
@Override
public boolean test(int value) {
return value % 3 == 0;
}
});
System.out.println("--------------------------------");
// 람다식
pt.printSome(num -> num % 3 == 0);
pt.printSome(num -> num > 5);
}
}
'⛏️ > JAVA' 카테고리의 다른 글
[JAVA] 45. 자바 I/O(input/ouput)와 스트림 (1) | 2023.12.05 |
---|---|
[JAVA] 44. 스레드(thread) (1) | 2023.11.28 |
[JAVA] 42. 람다식(Lambda Expressions) (0) | 2023.11.24 |
[JAVA] 41. 익명(anonymous) 객체 (0) | 2023.11.24 |
[JAVA] 40. 중첩 클래스, 중첩 인터페이스 (0) | 2023.11.08 |