Stream.allMatch ()가 빈 스트림에 대해 true를 반환하는 이유는 무엇입니까?
제 동료와 저는 빈 스트림 호출 allMatch()이 반환 될 것이라는 가정으로 인해 버그가있었습니다 false.
if (myItems.allMatch(i -> i.isValid()) {
//do something
}
물론 문서를 읽지 않고 가정하는 것은 우리의 잘못입니다. 그러나 내가 이해하지 못하는 allMatch()것은 빈 스트림에 대한 기본 동작이 true. 그 이유는 무엇입니까? anyMatch()(반대로 false를 반환하는) 와 마찬가지로이 작업은 모나드를 떠나 if명령문 에서 사용되는 명령형 방식으로 사용됩니다 . 이러한 사실을 고려할 때 대부분의 경우 빈 스트림에서 allMatch()기본값을 true사용하는 것이 바람직한 이유 가 있습니까?
이것은 공허한 진실로 알려져 있습니다 . 빈 컬렉션의 모든 구성원이 조건을 충족합니다. 결국 그렇지 않은 것을 가리킬 수 있습니까?
마찬가지로, 조건과 일치하는 컬렉션 요소를 찾을 수 없으므로를 anyMatch반환 false합니다. 이것은 많은 사람들에게 혼란 스럽지만 빈 세트에 대해 "any"및 "all"을 정의하는 가장 유용하고 일관된 방법으로 밝혀졌습니다.
호출 할 때 list.allMatch(또는 다른 언어로 된 유사어)의 항목 list이 술어와 일치하지 않는지 감지하고 싶습니다 . 항목이 없으면 일치하지 않을 수 있습니다. 내 다음 논리는 항목을 선택하고 조건 자와 일치 할 것으로 예상합니다. 빈 목록의 경우 항목을 선택하지 않고 논리는 여전히 유효합니다.
빈 목록이 allMatch반환 되면 어떻게 false됩니까?
내 간단한 논리는 실패합니다.
if (!myList.allMatch(predicate)) {
throw new InvalidDataException("Some of the items failed to match!");
}
for (Item item : myList) { ... }
수표를 !myList.empty() && !myList.allMatch().
요컨대, 빈 목록을 allMatch반환 true하는 것은 논리적으로 건전 할뿐만 아니라 실행의 행복한 경로에 있으며 확인이 더 적게 필요합니다.
이에 대해 생각하는 또 다른 방법이 있습니다.
allMatch()이다 &&무엇 sum()이다+
다음 논리 문장을 고려하십시오.
IntStream.of(1, 2).sum() + 3 == IntStream.of(1, 2, 3).sum()
IntStream.of(1).sum() + 2 == IntStream.of(1, 2).sum()
이것은 sum()단지 일반화 이기 때문에 의미 가 있습니다 +. 그러나 요소를 하나 더 제거하면 어떻게됩니까?
IntStream.of().sum() + 1 == IntStream.of(1).sum()
IntStream.of().sum()특정 방식으로, 또는 빈 숫자 시퀀스의 합 을 정의하는 것이 합리적이라는 것을 알 수 있습니다 . 이것은 우리에게 합산의 "정체성 요소"또는 무언가에 추가 될 때 효과가없는 값 ( 0)을 제공합니다.
같은 논리를 Boolean대수에 적용 할 수 있습니다 .
Stream.of(true, true).allMatch(it -> it) == Stream.of(true).allMatch(it -> it) && true
보다 일반적으로 :
stream.concat(Stream.of(thing)).allMatch(it -> it) == stream.allMatch(it -> it) && thing
그렇다면 stream = Stream.of()이 규칙을 적용해야합니다. 이 문제를 해결하기 위해 &&의 "identity element"를 사용할 수 있습니다. true && thing == thing, 그래서 Stream.of().allMatch(it -> it) == true.
그것의 기초가 수학적 귀납처럼 보입니다. 컴퓨터 과학의 경우이를 적용하는 것이 재귀 알고리즘의 기본 사례가 될 수 있습니다.
스트림이 비어 있으면 정량화가 막연하게 충족되었다고하며 항상 참입니다. Oracle Docs : 스트림 작업 및 파이프 라인
여기서 핵심은 본질적으로 다소 오해의 소지가있는 "진공 적으로 만족"한다는 것입니다. Wikipedia에는 그것에 대해 적절한 토론이 있습니다.
순수 수학에서 막연하게 참된 진술은 일반적으로 그 자체로 흥미롭지는 않지만 수학적 귀납법에 의한 증명의 기본 사례로 자주 발생합니다. Wikipedia : 공허한 진실
'program story' 카테고리의 다른 글
| jekyll 로컬 개발 중에 site.url을 localhost로 변경하십시오. (0) | 2020.10.27 |
|---|---|
| Ant에서 상대 경로를 절대 경로로 어떻게 변환합니까? (0) | 2020.10.27 |
| 정신적으로 Lisp / Clojure 코드를 읽는 방법 (0) | 2020.10.27 |
| 타이포그래피에서 CSS 문자 간격과 "추적"을 계산하는 방법은 무엇입니까? (0) | 2020.10.27 |
| foldr를 사용하여 foldl 작성 (0) | 2020.10.27 |