람다 표현식과 이어져 있으니, 복습하고 올 것! (특히 심화 부분)
1. 함수형 인터페이스란?
하나의 추상 메서드를 가지는 인터페이스 람다 표현식을 사용하여 인터페이스의 추상 메서드를 구현할 수 있다.
람다 표현식과 함께 많이 사용 됨.
람다 표현식은 함수형 인터페이스의 구현을 간단하고 간결하게 작성할 수 있는 방법
[ 함수형 인터페이스의 종류 ]
1. Function 인터페이스란?
자바에서 제공하는 함수형 인터페이스 Function 인터페이스는 입력값을 받아서 결과값을 반환하는 함수를 표현하기 위해 사용한다. 일반적으로 제네릭 타입을 사용하여 입력값과 결과값의 타입을 지정할 수 있다. ( = 매개변수의 타입과 반환 타입이 정해져 있지 않다.)
제네릭 타입 매개변수에는 참조 타입만 사용할 수 있기 때문에
Function은 랩핑으로만 넣을 수 있다. (int → Integer / double → Double)
2. Function 인터페이스의 형태
//map()은 Function 인터페이스를 활용하는 메서드 중 하나
[ 일반적인 형태 ]
interface Able { void hello(int value); }
[ Function 인터페이스로 구현한 형태 ]
interface Able<T, R> { R hello(T value); } ----------------------------------------- interface Able { void hello(int value); } public class Main { public static void main(String[] args) { Function<Integer, Void> function = (value) -> { System.out.println("Hello, " + value); return null; }; Able able = function::apply; able.hello(123); } }
만약, value에다 숫자를 넣으면 T는 Integer타입이 된다. R = 리턴을 나타내고, 마찬가지로 Integer를 넣으면 Integer타입. Function 인터페이스는 매개변수의 타입과 리턴 타입이 정해져있지 않다. 호출하고, 리턴할 때 결정됨.
3. 예제
1,2,3,4 는 처음엔 int로 받았지만 List 타입(컬렉션)으로 변경됐기 때문에 람다할 때 Integer 로 랩핑해서 받는다.
Arrays.asList() 메서드로 생성된 리스트는 고정 크기의 리스트로, 값의 추가나 삭제가 불가능 * 컬렉션 타입 -> 원시 자료형은 모두 랩핑해서 받는다. Arrays.asList() = 배열을 List 타입으로 받아라.
<해당 부분은 람다에서 return void하는 그걸 보고오기>
i = Integer (다 치기 번거로워서 한글자로 줄여서 작성)
toList() 메소드는 스트림(Stream)을 리스트(List)로 변환하는 메소드
asList()는 배열을 List로 변환!
[자바] list.stream() == [자바 스크립트] ... (전개 연산자)
흩뿌려지는 것 = 타입을 벗긴 것 = 현재 타입이 없는 형태
4. 컬렉션 복사
[ 처음에 Arrays.asList(1,2,3,4); 로 하는 법 ]
public class CopyEx01 { public static void main(String[] args) { var list = Arrays.asList(1,2,3,4); // 컬렉션 복사 List<Integer> newList = new ArrayList<>(list); newList.add(5); System.out.println(newList); System.out.println(list.size()); System.out.println(newList.size()); System.out.println(list.hashCode()); System.out.println(newList.hashCode());
[ 처음에 List<Integer> list = new ArrayList<>(); 로 하는 법 ]
public class CopyEx01 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); // 컬렉션 복사 List<Integer> newList = new ArrayList<>(list); newList.add(5); System.out.println(newList); System.out.println(list.size()); System.out.println(newList.size()); System.out.println(list.hashCode()); System.out.println(newList.hashCode());
1. Predicate 인터페이스
단일 인자를 받아서 boolean 값을 반환하는 메서드를 정의하는 함수형 인터페이스 조건을 만족하면 true를 반환하고, 만족하지 않으면 false를 반환 주로 조건을 검사하거나 필터링하는데 사용
Predicate 인터페이스를 사용하여 null이 아닌 값을 검사하는 람다 표현식
(제네릭 타입을 명시하지 않았으므로,
Object
타입의 값을 검사)[ 예시 ]
하나의 추상 메서드 test 있는 것 확인! -> 함수형 인터페이스
return str.length() > 5;는 test 메서드의 구현부분 주어진 문자열 str의 길이가 5보다 큰지를 검사하는 로직 만약 str의 길이가 5보다 크다면, true를 반환하고 그렇지 않다면 false를 반환 >> 이걸 람다식으로 사용
2. Supplier 인터페이스
매개변수가 없고, 값을 반환하는 메서드를 가진 함수형 인터페이스 * 값을 생성하는 로직을 담고 있는 메서드를 표현하고 싶을 때 사용 * 매개변수가 없고, 값을 반환하는 람다 표현식을 사용하고자 할 때 사용
매개변수 없고, 리턴 있고
3. Consumer 인터페이스
단일 매개변수를 받아서 그 값을 어떤 방식으로든 처리(소비)하는 동작을 구현 (값 반환 X) * 어떤 작업을 수행하고자 할 때, 인자를 받아서 처리하는 로직을 구현할 때 사용 * 컬렉션의 요소에 대해 특정 동작을 수행하기 위해 사용 ex) 리스트의 모든 요소에 대해 특정 연산을 수행할 때
소비하다 = 해당 값을 활용하여 원하는 동작을 수행하는 것을 의미
입력값을 받아서 어떠한 동작을 수행하고 반환하지 않는
accept
메서드Consumer<String> 타입의 객체를 생성한다고 가정해보자. 이 객체는 문자열을 입력받아서 그 값을 활용하여 원하는 동작을 수행한다. 이 동작은 accept 메서드를 통해 정의된다.
//람다로 변형
Consumer<String> 타입의 printString 객체를 생성하고, 입력받은 문자열을 출력하는 동작을 accept 메서드의 구현부인 System.out.println(text)로 정의하고 있다. 이제 printString 객체를 사용하여 다음과 같이 문자열을 출력할 수 있다.
"안녕하세요"를 매개변수 (받는 변수명 : text) 로 받아서 "안녕하세요" -> System.out.println("안녕하세요"); 형식으로 동작하게 하는 것이 '소비', Consumer 인터페이스 이렇게 값(인자)을 받아서 그 값을 활용하여 원하는 동작을 수행하는 역할을 한다.
이것 외에도 ActionListener, Comparator 등 많다.
Share article