2017-04-14 11 views
9

목적은 스트림 필터에 사용할 수있는 새로운 조건식 생성하는 것이다Java 함수에서 술어와 함수를 적절하게 작성하는 방법은 무엇입니까?

myCollectionOfElement 
.stream() 
.filter(
    MyStaticHelperClass.compose(MyStaticHelperClass.getSubElement1OfTheElement(),MyStaticHelperClass.getPredicate1OnSubElement1())) 
.sorted(MyStaticHelperClass.getOtherSubElement().reversed()) 
.limit(10) 
.collect(Collectors.toList()) 

getSubElement1OfTheElement() 복귀 Function<E,S> (E는 S 속성을 포함) getPredicate1OnSubElement1() 복귀

I이 방법 참조를 노출시키는 고정 기능을 사용 Predicate<S> 및 기능. 속도 템플릿에서 스트림이 호출되고이 컨텍스트 이 람다 구문과 메서드 참조을 지원하지 않기 때문에이 작업을 수행합니다. 모든 가능한 조합에 대해 정적 함수를 생성하고 싶지 않으므로이 변수들을 조합 가능하게 만들고 싶습니다..

여기서 예를 들어, 및 getPredicate1OnSubElement1()을 작성할 수 있기 때문에 정적 인 getPredicate1OnElementThatCheckProperty1OnTheSubElement1()을 갖고 싶지 않습니다.

그래서 내가 작성 기능이 필요합니다

// returns a new Predicate constructed by applying Predicate predicate on the result of Function function 
public static <E,S> Predicate<E> compose(Function<E,S> function, Predicate<S> predicate) 

// most intuitive : lambda 
return value -> predicate.test(function.apply(value)); 

// with method references 
return function.andThen(predicate::test)::apply; 
// predicate.compose is not available because Predicate interface doesn't extends Function interface 

에 의해 영감을 Is there a convenience method to create a Predicate that tests if a field equals a given value?

// step by step with variables 
Function <S,Boolean> predicateFunction = predicate::test; 
// a kind of @FunctionalInterface implicit "conversion" ? Predicate -> Function. 
// is that safe ? 

Function <E,Boolean> composed = function.andThen(predicateFunction::apply); 
return composed::apply; 

편집 : https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

,536,913 : 그것은 주조 컨텍스트라고

// the implementation of my compose can also be this ugly one-liner : 
return ((Function <S,Boolean>)predicate::test).compose(function)::apply; 

그래서 우리는 추상 메소드의 이름이 각 인터페이스 (테스트와 나의 경우에는 적용)마다 다르므로 어떤 함수형 인터페이스 (함수와 술어)를 취하는 일반적인 작성 함수를 구현할 수 없습니다.
나는 그걸로 괜찮습니다.

결론적으로, 필자가 정말로 필요로하는 것은 두 가지 정적 함수, 즉 술어를 함수로 변환하고 그 반대의 것을 말합니다. 모든 Predicate는 Function으로 사용되며 최종 조작은 작성된 Function을 Predicate로 변환하여 필터 함수의 매개 변수 유형과 일치시킵니다.

public static <S> Function<S,Boolean> predicateToFunction(Predicate<S> predicate){ 
    return predicate::test; 
} 
public static <S> Predicate<S> functionToPredicate(Function<S,Boolean> function){ 
    return function::apply; 
} 

는 것이 맞습니까?
그렇다면 함수 서명의 경계를 해제하는 데 관심이 있습니까?

+0

당신이 달성하려고하는지 설명 할 수 :

value -> predicate.test(function.apply(value)); 

아니면 작성 기능을 작성해야 당신이 정말로/싶은 경우는, 서명은 같은 것을해야? –

+2

JDK에 내장되어 있지 않은 이유는 람다를 명시 적으로 작성하는 것이 더 간단하기 때문입니다. –

+0

@JacobG. 문맥을 설명하기 위해 내 게시물을 편집했습니다. – fdelsert

답변

3

나는 내 자신의 질문에 답합니다.

사용 람다 :

public static <E,S> Predicate<E> compose(Function<E,S> function, Predicate<? super S> predicate)