귀하의 문제가 c
비록 당신의 조건에 매개 변수입니다 때문에, 다른 술어마다 사용하고 있다는 것입니다, p
도 다릅니다
이
final Node p;
Predicate<Node> matchesParentId = c -> p.id() == c.id();
기존의 코드를 확인 컴파일 이유는 p
는 점이다 은 forEach
블록의 범위에 실제로 최종이므로, 해당 범위 내의 Predicate
에서 최종 필드로 사용할 수 있으며, 수명은 1 회 forEach
반복입니다.
당신은 할 수 :
parentList.forEach(p -> {
childList
.stream()
.filter(matchesId(p))
.<...continue working on stream...>
});
private Predicate<Node> matchesId(Node other) {
return node -> node.id() == other.id();
}
하지만 당신은 p
이 변화로 하나 Predicate
를 생성하고 재사용 할 수 없습니다.
당신은 BiPredicate
및 curry을 Predicate
로를 작성할 수 있습니다. 불행히도 Java는 카레 메서드를 제공하지 않으므로 직접 제공해야합니다.
private <T,U> Predicate<U> curry(BiPredicate<T,U> biPredicate, T t) {
return u -> biPredicate.test(t, u);
}
BiPredicate<Node,Node> nodesMatch = (a,b) -> a.id() == b.id();
parentList.forEach(p -> {
childList
.stream()
.filter(curry(nodesMatch, p))
.<...continue working on stream...>
});
이것은 이전 솔루션보다 훨씬 많은 것을 구매하지는 않지만 조금 더 FP-nerdy입니다. p
에 대해 여전히 새로운 Predicate
을 생성하고 있습니다. 물론 curry()
메소드를 사용하는 대신 인라인으로 처리 할 수 있습니다.
.filter(c -> nodesMatch.test(p, c))
동적으로 연결하려면 BiPredicate<Node,Node>
을 선택할 수 있습니다. BiPredicate
을 초기화하는 데 비용이 많이 든다면, 많은 사람들이이를 대기로 싸서 싸게 될 것입니다.
또는 당신이 술어에 전체를 제출 할 수있는 하나의 객체로 p
및 c
을 매핑 할 수 있습니다 : 여기
Predicate<Pair<Node,Node>> nodesMatch = pair ->
pair.left().id() == pair.right().id();
parentList.forEach(p -> {
childList
.stream()
.map(c -> new Pair<Node>(c, p))
.filter(nodesMatch)
.map(pair -> pair.left())
.<...continue working on stream...>
});
(Pair
입니다 가상하지만, 제 3의 숫자 (예 : 구아바)가 하나를 제공하거나 자신의 롤을 사용하거나 new Node[] { c, p }
를 사용하십시오.
현재'filter()'호출의 문제점은 무엇입니까? – Eran
다른 곳에서이 필터를 재사용하려는 경우 - 복사/붙여 넣기를 피하십시오. 그것 이외에 - 아무것도. – lapkritinis
단순한 술어에서는 복사/붙여 넣기를 피할 가치가 없습니다. 복잡한 조건을 가지고 있다면, 그 곳에서 호출 할 수있는 메소드를 만든 다음'c -> someMethodComparing (c, p)'를 사용하십시오. – lucasvw