자바 8 방법 참조 사용 안내
방법 참조
자바 8 에서 우 리 는 방법 으로 인용 할 수 있다 는 것 은 잘 알려 져 있다.예 를 들 어 우리 가 스 트림 요 소 를 옮 겨 다 닐 때
String::isEmpty
방법 을 참조 할 수 있다.다음 코드 를 보십시오.Stream.of("A", "", "B").filter(Stream::isEmpty).count();
실행 결 과 는 1 입 니 다.그러나 빈 문자열 을 걸 러 내 려 면
isEmpty
으로 써 야 합 니 다.이것 은 Lambda 표현 식 입 니 다.분명히 여기 에는 싫 은 비대 칭 상상 이 있다.우 리 는 방법 을 써 서 인용 할 수 있 지만,그것 의 반식 을 써 서 는 안 된다.우 리 는 쓸 수 있 지만 쓸 수 없다.filter(s -> !s.isEmpty())
또는predicate.negate()
.왜 일 까요?람 다 표현 식 이나 함수 인터페이스 가 아 닌 방법 을 인용 하기 때 문 입 니 다.단,자바 의 유형 추 도 를 사용 하면 방법 인용 을 하나 이상 의 함수 인터페이스 로 해석 할 수 있 습 니 다.상례
Stream::isEmpty.negate()
는 적어도 다음 과 같이 해석 할 수 있다.Predicate<String>
Function<String, Boolean>
따라서 우 리 는 다른 가능성 을 배제 하고 방법 인용 을 어떤 함수 인터페이스 로 바 꾸 는 지 확인 해 야 한다.본문 은 어느 정도 에 이 문 제 를 해결 했다.글 의 코드 는 오픈 소스 프로젝트 Speedment 에서 나 왔 습 니 다.데이터 베 이 스 를 자바 8 의 흐름 처럼 보이 게 합 니 다.
해석 방법 참조
사실은 정적 방법 을'파이프'로 하여 이 문 제 를 부분적으로 해결 할 수 있 습 니 다.이 정적 방법 은 하나의 방법 으로 입력 하고 특정한 함수 인 터 페 이 스 를 되 돌려 줍 니 다.아래 의 간단 한 정적 방법 을 고려 해 보 세 요.
public static <T> Predicate<T> as(Predicate<T> predicate) {
return predicate;
}
지금 이 방법 을 정적 으로 가 져 오 면 사실상 우 리 는 더욱 간단하게 방법 을 인용 할 수 있다.다음 과 같은 예 에서 보 듯 이:
Stream.of("A", "", "B").filter(as(String::isEmpty).negate()).count();
이 코드 가 되 돌아 온 결 과 는 2,즉 흐 르 는 비 공 원소 의 수량 입 니 다.방법 인용 에 관 한 사용 방식 에 대해 우 리 는 또 한 걸음 앞으로 나 아 갔다.또 다른 장점 은 이 솔 루 션 이 predicates 인 터 페 이 스 를 쉽게 만 드 는 것 입 니 다.예 를 들 어:
.filter(as(String::isEmpty).negate().and("A"::equals))
모든 방법 참조 분석
하지만 아직 해결 해 야 할 문제 가 있다.우 리 는 많은 정적
!Stream::isEmpty
함 수 를 마음대로 만 들 수 없다.왜냐하면 하나의 방법 은 여러 가지String::isEmpty
방법 으로 해석 할 수 있 기 때문이다.본 고 에서 처음에 언급 한 것 처럼.따라서 더욱 절묘 한 해결 방안 은 함수 인터페이스 유형 명 을 모든 정적 방법 에 추가 하 는 것 이다.그러면 우 리 는 모든 함수 인터페이스 변환 방법 에 특정한 방법 을 선택 하여 인용 할 수 있다.모든 방법의 인용 을 자바 표준 패키지`java.util.function 에서 임의로 일치 하 는 함수 인터페이스 로 변환 할 수 있 는 도구 클래스 가 있 습 니 다.GitHub 에서 최신 버 전 을 직접 다운로드 합 니 다.
import java.util.function.*;
/**
*
* @author Per Minborg
*/
public class FunctionCastUtil {
public static <T, U> BiConsumer<T, U> asBiConsumer(BiConsumer<T, U> biConsumer) {
return biConsumer;
}
public static <T, U, R> BiFunction<T, U, R> asBiFunction(BiFunction<T, U, R> biFunction) {
return biFunction;
}
public static <T> BinaryOperator<T> asBinaryOperator(BinaryOperator<T> binaryOperator) {
return binaryOperator;
}
public static <T, U> BiPredicate<T, U> asBiPredicate(BiPredicate<T, U> biPredicate) {
return biPredicate;
}
public static BooleanSupplier asBooleanSupplier(BooleanSupplier booleanSupplier) {
return booleanSupplier;
}
public static <T> Consumer<T> asConsumer(Consumer<T> consumer) {
return consumer;
}
public static DoubleBinaryOperator asDoubleBinaryOperator(DoubleBinaryOperator doubleBinaryOperator) {
return doubleBinaryOperator;
}
public static DoubleConsumer asDoubleConsumer(DoubleConsumer doubleConsumer) {
return doubleConsumer;
}
public static <R> DoubleFunction<R> asDoubleFunction(DoubleFunction<R> doubleFunction) {
return doubleFunction;
}
public static DoublePredicate asDoublePredicate(DoublePredicate doublePredicate) {
return doublePredicate;
}
public static DoubleToIntFunction asDoubleToIntFunction(DoubleToIntFunction doubleToIntFunctiontem) {
return doubleToIntFunctiontem;
}
public static DoubleToLongFunction asDoubleToLongFunction(DoubleToLongFunction doubleToLongFunction) {
return doubleToLongFunction;
}
public static DoubleUnaryOperator asDoubleUnaryOperator(DoubleUnaryOperator doubleUnaryOperator) {
return doubleUnaryOperator;
}
public static <T, R> Function<T, R> asFunction(Function<T, R> function) {
return function;
}
public static IntBinaryOperator asIntBinaryOperator(IntBinaryOperator intBinaryOperator) {
return intBinaryOperator;
}
public static IntConsumer asIntConsumer(IntConsumer intConsumer) {
return intConsumer;
}
public static <R> IntFunction<R> asIntFunction(IntFunction<R> intFunction) {
return intFunction;
}
public static IntPredicate asIntPredicate(IntPredicate intPredicate) {
return intPredicate;
}
public static IntSupplier asIntSupplier(IntSupplier intSupplier) {
return intSupplier;
}
public static IntToDoubleFunction asIntToDoubleFunction(IntToDoubleFunction intToDoubleFunction) {
return intToDoubleFunction;
}
public static IntToLongFunction asIntToLongFunction(IntToLongFunction intToLongFunction) {
return intToLongFunction;
}
public static IntUnaryOperator asIntUnaryOperator(IntUnaryOperator intUnaryOperator) {
return intUnaryOperator;
}
public static LongBinaryOperator asLongBinaryOperator(LongBinaryOperator longBinaryOperator) {
return longBinaryOperator;
}
public static LongConsumer asLongConsumer(LongConsumer longConsumer) {
return longConsumer;
}
public static <R> LongFunction<R> asLongFunction(LongFunction<R> longFunction) {
return longFunction;
}
public static LongPredicate asLongPredicate(LongPredicate longPredicate) {
return longPredicate;
}
public static <T> LongSupplier asLongSupplier(LongSupplier longSupplier) {
return longSupplier;
}
public static LongToDoubleFunction asLongToDoubleFunction(LongToDoubleFunction longToDoubleFunction) {
return longToDoubleFunction;
}
public static LongToIntFunction asLongToIntFunction(LongToIntFunction longToIntFunction) {
return longToIntFunction;
}
public static LongUnaryOperator asLongUnaryOperator(LongUnaryOperator longUnaryOperator) {
return longUnaryOperator;
}
public static <T> ObjDoubleConsumer<T> asObjDoubleConsumer(ObjDoubleConsumer<T> objDoubleConsumer) {
return objDoubleConsumer;
}
public static <T> ObjIntConsumer<T> asObjIntConsumer(ObjIntConsumer<T> objIntConsumer) {
return objIntConsumer;
}
public static <T> ObjLongConsumer<T> asObjLongConsumer(ObjLongConsumer<T> objLongConsumer) {
return objLongConsumer;
}
public static <T> Predicate<T> asPredicate(Predicate<T> predicate) {
return predicate;
}
public static <T> Supplier<T> asSupplier(Supplier<T> supplier) {
return supplier;
}
public static <T, U> ToDoubleBiFunction<T, U> asToDoubleBiFunction(ToDoubleBiFunction<T, U> toDoubleBiFunction) {
return toDoubleBiFunction;
}
public static <T> ToDoubleFunction<T> asToDoubleFunction(ToDoubleFunction<T> toDoubleFunction) {
return toDoubleFunction;
}
public static <T, U> ToIntBiFunction<T, U> asToIntBiFunction(ToIntBiFunction<T, U> toIntBiFunction) {
return toIntBiFunction;
}
public static <T> ToIntFunction<T> asToIntFunction(ToIntFunction<T> ioIntFunction) {
return ioIntFunction;
}
public static <T, U> ToLongBiFunction<T, U> asToLongBiFunction(ToLongBiFunction<T, U> toLongBiFunction) {
return toLongBiFunction;
}
public static <T> ToLongFunction<T> asToLongFunction(ToLongFunction<T> toLongFunction) {
return toLongFunction;
}
public static <T> UnaryOperator<T> asUnaryOperator(UnaryOperator<T> unaryOperator) {
return unaryOperator;
}
private FunctionCastUtil() {
}
}
정적 으로 관련 방법 을 가 져 온 후에 우 리 는 이렇게 쓸 수 있다.
Stream.of("A", "", "B").filter(asPredicate(String::isEmpty).negate()).count();
더 좋 은 해결 방안
함수 인터페이스 자체 에 수신 방법 을 인용 하여 특정한 함수 인터페이스 로 전환 하 는 정적 방법 이 포함 되 어 있다 면 더욱 좋 을 것 입 니 다.예 를 들 어 표준 자바
as()
함수 인 터 페 이 스 는 이렇게 됩 니 다.@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {...}
default Predicate<T> negate() {...}
default Predicate<T> or(Predicate<? super T> other) {...}
static <T> Predicate<T> isEqual(Object targetRef) {...}
// New proposed support method to return a
// Predicate view of a Functional Reference
public static <T> Predicate<T> of(Predicate<T> predicate) {
return predicate;
}
}
그래서 우 리 는 이렇게 쓸 수 있다.
Stream.of("A", "", "B").filter(Predicate.of(String::isEmpty).negate()).count();
필 자 는 이렇게 하 는 것 이 매우 좋아 보인다 고 생각한다!
가장 가 까 운 Open JDK 개발 자 에 게 연락 해서 수정 제안 을 하 세 요!
OneAPM 은 엔 드 에서 엔 드 까지 의 자바 응용 성능 솔 루 션 을 제공 할 수 있 습 니 다.저 희 는 흔히 볼 수 있 는 자바 프레임 워 크 와 응용 서버 를 지원 합 니 다.시스템 병목 을 신속하게 발견 하고 이상 근본 원인 을 찾 을 수 있 습 니 다.분 급 배치,즉각 체험,자바 모니터링 은 이렇게 간단 한 적 이 없 었 다.더 많은 기술 글 을 읽 으 려 면 OneAPM 공식 기술 블 로 그 를 방문 하 세 요.
본 고 는 OneAPM 공식 블 로그 에서 이전 되 었 다.
원본 주소:https://dzone.com/articles/put-your-java-8-method-references-to-work
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.