Java/스트림(Stream)

[Java]anyMatch, allMatch, noneMatch 메서드 정리

DevStory 2022. 8. 26.

anyMatch, allMatch, noneMatch 메서드

Stream에 특정 조건을 만족하는 값이 존재하는지 확인하기 위해 사용되는 anyMatch(), allMatch(), noneMatch() 메서드는 비슷하게 동작하므로 헷갈릴 수 있습니다.

 

이번 포스팅은 anyMatch(), allMatch(), noneMatch() 메서드 공통점 및 차이점을 간략하게 설명합니다.


메서드 설명

anyMatch() 메서드

- 스트림에서 특정 조건을 만족하는 요소가 하나라도 있는 경우 true를 반환하고 더 이상 실행되지 않습니다.

 

allMatch() 메서드

- 스트림에서 모든 요소가 특정 조건을 만족하는 경우 true를 반환합니다. 특정 조건을 만족하지 않는다면, false를 반환하고 더 이상 실행되지 않습니다.

 

noneMatch() 메서드

- 스트림에서 특정 조건을 만족하는 요소가 하나라도 있는 경우 false를 반환하고 더 이상 실행되지 않습니다.


공통점

  • 특정 조건을 만족하는 경우 더 이상 호출되지 않으므로 단락 종료 오퍼레이션(short-circulting terminal operation)입니다. anyMatch() 메서드는 조건문이 true인 경우 더 이상 호출되지 않으며, anyMatch() 메서드는 조건문이 false인 경우 더 이상 호출되지 않습니다.
  • 매개변수가 함수형 인터페이스인 Predicate로 동일합니다. Predicate 인터페이스는 한 개의 매개변수를 가지며, Boolean 타입의 값을 반환하는 작업을 수행하기 위해 사용됩니다.

동작 과정 확인

먼저, anyMatch(), allMatch() 메서드 동작 과정을 살펴봅니다.

 

Integer 타입의 List를 Stream으로 변환 후 동작 과정을 확인하기 위해 콘솔에 값을 출력합니다.

public static void main(String args[]) {
  List<Integer> intList = new ArrayList<>(Arrays.asList(2, 2, 4, 2));

  System.out.println("[anyMatch 동작 과정]");
  boolean isAnyMatch = intList.stream().anyMatch(num -> {
      System.out.println("현재 요소: " + num);
      return num == 2;
  });
  System.out.println("2인 요소가 하나라도 존재하는가?: " + isAnyMatch + "\n");

  System.out.println("[allMatch 동작 과정]");
  boolean isAllMatch = intList.stream().allMatch(num -> {
      System.out.println("현재 요소: " + num);
      return num == 2;
  });
  System.out.println("모든 요소가 2인가?: " + isAllMatch + "\n");
}

[실행 결과]

[anyMatch 동작 과정]
현재 요소: 2
2인 요소가 하나라도 존재하는가?: true

[allMatch 동작 과정]
현재 요소: 2
현재 요소: 2
현재 요소: 4
모든 요소가 2인가?: false

실행 결과에서 확인할 수 있듯이 anyMatch() 메서드는 특정 조건을 만족하는 요소가 하나라도 존재하면, true를 반환하고 allMatch() 메서드는 모든 요소가 특정 조건을 만족하면 true를 반환하고 그렇지 않으면 false를 반환합니다.

 

다음 예제는 noneMatch() 메서드 동작 과정입니다.

 

noneMatch() 메서드는 특정 조건을 만족하는 요소가 하나라도 존재하면, false를 반환하고 그렇지 않으면 true를 반환합니다.

public static void main(String args[]) {
  List<Integer> intList = new ArrayList<>(Arrays.asList(1, 2, 3, 4));

  System.out.println("[noneMatch 동작 과정]");
  boolean isNoneMatch = intList.stream().noneMatch(num -> {
      System.out.println("현재 요소: " + num);
      return num == 2;
  });
  
  System.out.println("2인 요소가 하나라도 존재하는가?: " + !isNoneMatch + "\n");
}

[실행 결과]

[noneMatch 동작 과정]
현재 요소: 1
현재 요소: 2
2인 요소가 하나라도 존재하는가?: true

차이점 - 스트림이 빈 값인 경우

이 세 가지 메서드는 스트림이 비어 있는 경우 다르게 동작합니다.

public static void main(String args[]) {
  List<Integer> intList = new ArrayList<>();

  boolean isAnyMatch = intList.stream().anyMatch(num -> num == 2);
  boolean isAllMatch = intList.stream().allMatch(num -> num == 2);
  boolean isNoneMatch = intList.stream().noneMatch(num -> num == 2);

  System.out.println("Stream이 빈 값인 경우 anyMatch() 반환 결과?: " + isAnyMatch);
  System.out.println("Stream이 빈 값인 경우 allMatch() 반환 결과?: " + isAllMatch);
  System.out.println("Stream이 빈 값인 경우 noneMatch() 반환 결과?: " + isNoneMatch);
}

[실행 결과]

Stream이 빈 값인 경우 anyMatch() 반환 결과?: false
Stream이 빈 값인 경우 allMatch() 반환 결과?: true
Stream이 빈 값인 경우 noneMatch() 반환 결과?: true

anyMatch() 메서드

- false를 반환합니다.

 

allMatch() 메서드

- 수학과 논리학에서 사용되는 공허한 진실이라는 개념이 적용되어 true를 반환합니다.

 

noneMatch() 메서드

- anyMatch() 메서드의 반환 결과를 부정하므로 true를 반환합니다.


noneMatch 메서드의 반대는?

noneMatch() 메서드를 공부하다 보면 누군가는 noneMatch() 메서드의 반대는 allMatch() 메서드라고 말하며, 누군가는 anyMatch() 메서드라 말합니다.

 

개인적으로 "noneMatch() 메서드의 반대는 없다."라고 생각합니다.

 

아래는 제 개인적인 의견입니다.

 

첫 번째 근거

사용 목적이 다르며, Oracle에서 이유 없이 NoneMatch() 메서드를 만들지 않았을 것입니다.

[Oracle에서 설명하는 noneMatch() 메서드]

 

두 번째 근거 - allMatch() 메서드의 반대가 아닌 이유

스트림이 비어 있을 경우 allMatch() 메서드와 noneMatch() 메서드의 반환 결과가 동일합니다. 따라서, noneMatch() 메서드의 반대를 allMatch() 메서드라고 생각하기 어렵습니다.

 

세 번째 근거 - anyMatch() 메서드의 반대가 아닌 이유

anyMatch() 메서드는 조건을 만족하는 값이 하나라도 존재하면, 더 이상 호출되지 않습니다. noneMatch() 메서드도 조건을 만족하는 값이 하나라도 존재하면, 더 이상 호출되지 않습니다.

 

noneMatch() 메서드가 anyMatch() 메서드의 반대라면, "조건을 만족하지 않는 값이 하나라도 존재하면 더 이상 호출되지 않는 게 맞지 않을까?"라고 생각합니다.

 

결론

반대라는 개념이 동작 방법의 반대인지 반환 결과의 반대인지 모호하므로 noneMatch() 메서드의 반대는 없다고 생각합니다.

반응형

댓글