🏃♂️ 들어가기 앞서..
본 게시물은 스터디 활동 중에 작성한 게시물로 자바의 정석-기초편 교재를 학습하여 정리하는 글입니다.
※ 스터디 Page : 〔투 비 마스터 : 자바〕
*해당 교재의 목차 순서와 구성을 참고하여 작성하며
각 내용마다 부족할 수 있는 내용이나 개인적으로 궁금한 점은
추가적인 검색을 통해 채워나갈 예정입니다.
java.util.function
패키지자중 사용되는 다양한 " 함수형 인터페이스 " 제공
일일이 사용할 때마다
새로운 함수형 인터페이스를 만들어서 구현하는
불필요한 작업을
자주 사용되는 유형에 맞춰
미리 표준화된 함수형 인터페이스를 제공해준 것이
java.util.function
패키지 이다.
덕분에
함수형 인터페이스에 정의된 메서드 이름도 통일되고
재사용성 / 유지보수 측면에서 좋다는
장점이 있다.
대표적으로 자주 쓰이는
가장 기본적인 함수형 인터페이스는 아래와 같다.
" 매개변수 " & " 반환값 유무 "에 따라 4가지로 분류
java.lang.Runnable
: 매개변수 X / 반환값 X --[메서드]--> void run()
Supplier<T>
: 매개변수 X / 반환값 O --[메서드]--> T get()
Consumer<T>
: 매개변수 O / 반환값 X --[메서드]--> void accept(T t)
Function<T,R>
: 매개변수 O / 반환값 O (일반적인 함수) --[메서드]--> R apply(T t)
Function<T,R>
▶ 반환값 boolean == Predicate<T>
Predicate<T>
: 조건식을 표현하는데 사용됨. --[메서드]--> boolean test(T t)
《 사용 방법 》
Predicate<String> isEmptyStr = s -> s.length() == 0 ; // 연산결과가 boolean형의 실행문
String s = "";
if (isEmptyStr.test(s)) // if(s.length() == 0) 동일
System.out.println("Empty String!!");
위에서 알아본 인터페이스는
말했다시피
가장 기본적인 인터페이스이고
더 나아가
매개변수가 2개인 함수형 인터페이스도 존재한다.
( 말 그대로 2개이기 때문에 Bi
라는 키워드가 앞에 붙는다. )
" 매개변수 "가 2개인 함수형 인터페이스 ( 반환값 여부가 기준이 되지 않음!! )
BiConsumer<T,U>
void accept(T t, U u)
BiFunction<T,U,R>
R apply(T t, U u)
BiPredicate<T>
boolean test(T t, U u)
이번에는
매개변수의 "타입"과 반환값의 "타입"이
일치한다는 특징을 가진 함수형 인터페이스로
" 단항 연산자 " 와 " 이항 연산자 "로 나눠진다.
타입이 일치하기 때문에 제네릭스엔 타입이 하나만 작성되어 있다.
★ 공통 : " 투입 & 반환 타입 동일 "
UnaryOperator<T>
T apply(T t)
Function
의 자손@FunctionalInterface
// Function의 자손
public interface UnaryOperator<T> extend Function<T, T> {
static <T> UnaryOperator<T> identity() { // 항등함수 유형
return t -> t; //
}
}
BinaryOperator<T>
T apply(T t, T t)
BiFunction
의 자손해당 특징을 제외하면
앞서 알아봤던
Function
과 동일하다.
조금 위의
UnaryOperator
의 예시에서
" static에 제네릭이 붙어있는 것 "을 제네릭 메서드 라고 한다.
static은 인스턴스가 생성되기 전에 먼저 메모리에 올라가게 되는데
이 코드를 살펴보자.// 오류 발생 public class Member<T> { static T getName(T name){ return name ; } }
위와같이
해당 클래스 타입 객체를 매개변수로 받거나 반환타입이 해당 클래스 타입이라면인스턴스가 생성되기 전까진
T의 타입이 뭔지 정해지지 않기 때문에 오류가 발생하는 것이다.그 때, 아래와 같이
public class Member<T> { static <T> getName(T name){ return name ; } }
코드상으로는 class의 제네릭
<T>
와 static 메서드의<T>
가
같아 보일 순 있지만
완전히 다른 별개의 제네릭 타입으로서
" 해당 클래스가 인스턴스화가 되지 않더라도 먼저 메모리에 올라갈 수 있도록 "
분리시켜 지정하는 방법이다.