ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA8] What is different things between findAny and findFirst? / findAny와 findFirst의 차이점에 대하여
    Backend/JAVA&JAVA8 2022. 5. 5. 14:02
    사진 삭제
     

    사진 설명을 입력하세요.

    안녕하세요.

    이전 시간에는 map과 filter에 대해 알아보았고 또한 그 차이점에 대해서 알아보았는데요.

    이번 시간에는 filter를 사용할 때에 사용하는 findFirst와, findAny 메소드들의 차이점에 대해서 알아볼게요.

     

     

    1. findAny()

    우선, findAny 메소드를 사용하면 Stream에서 어떠한 요소를 찾을 수 있습니다.

    순서에 구애받지 않고 요소를 찾을 때 사용하세요.

    예를 들어 아래와 같이 Integer로 이루어진 List가 있다고 가정하겠습니다.

    List<Integer> testResultList = Arrays.asList(1,2,3,2,1);
    Optional<Integer> resultOfFindAny = testResultList.stream().findAny();
     

    위와 같이 steram을 적용한 후 findAny 메소드를 사용하면 가장 처음 조건에 해당하는 값을 발견한 후 반환하게 됩니다. 아래와 같이 시스템 로그를 작성한 후...

    System.out.println("resultOfFindAny: " + resultOfFindAny);
    System.out.println("resultOfFindAny.get(): " + resultOfFindAny.get());
     

    출력 결과를 살펴보겠습니다..

    resultOfFindAny: Optional[1]
    resultOfFindAny.get(): 1
     

    1이 출력되신 것을 보실 수 있습니다.

    (Optional로 감싸신 경우에는 반드시 get으로 접근하실 수 있습니다)

    findAny()라는 메소드의 이름을 보면 무언가 이질적으로 느껴지실 겁니다.

    왜냐하면 메소드를 직역하게 되면 '아무거나 찾는다'이거든요. 하지만 1이 나왔습니다.

    어떠한 비밀이 숨겨진 걸까요?

    그 비밀은 병렬처리에 있습니다.

    Java8에서는 코드상으로 병렬처리에 대한 구현이 가능한데요.

    잠깐! 병렬처리가 무엇인가요?

    병렬처리란 말이죠...

     

     

    제가 현재 병렬처리에 대해 자세하게 이야기할 능력이 안되다 보니 링크로 대체하겠습니다.

    포스팅해주신 개발자님께 감사드리고 만약 문제시 댓글 남겨주시면 삭제하도록 하겠습니다.

    findAny()에서는 '병렬처리가 아닌' 작업에서는 첫 번째 요소를 반환할 '가능성'이 높습니다.

    위의 코드처럼요.

    하지만 보장은 되지 않습니다. 제가 포스팅을 링크해드렸지만

    "그러니까, Java 상에서는 어떤 식으로 병렬처리를 한다는 건데?"

    하는 생각이 드실 겁니다.

     

    그렇다면 병렬처리 관련된 코드를 살펴보도록 하겠습니다.

    Java8에서는 코드상으로 병렬처리에 대한 구현이 가능한데요.

    Optional<Integer> resultOfFindAny2 = testResultList
                                           .stream()
                                           .parallel()
                                           .findAny();
    
    System.out.println("resultOfFindAny2.get(): " + resultOfFindAny2.get());
     

    출력 결과는 놀랍게도....

    resultOfFindAny2.get(): 3
     

    3입니다..!

     

    코드상에서 가장 빨리 뽑을 수 있는 요소에 대해 뽑은 것이죠.

    직렬 처리와 병렬처리에 대한 좋은 유튜브 동영상이 있어서 그 부분도 링크 걸어둘게요.

    제 포스팅이 길잡이와 정보 습득에 많은 도움이 되었으면 하는 바람이 있습니다.

     

    2.findFirst()

    위의 findAny()와는 다르게 findFirst()는 순서를 보장합니다.

    이전에 사용했던 병렬처리 구현 메소드와 함께 출력해볼까요?

    List<Integer> testResultList = Arrays.asList(1,2,3,2,1);
    Optional<Integer> resultOfFindFirst = testResultList
                                               .stream()
                                               .findFirst();
    
    
        if(resultOfFindFirst.isPresent()) {
            System.out.println("resultOfFindFirst: " + resultOfFindFirst); // 왼쪽과 마찬가지로 로그를 찍어버리면 Optional 로 감싸여져 있는 객체 자체를 반환합니다.
            System.out.println("resultOfFindFirst.get(): " + resultOfFindFirst.get());
        } else {
            System.out.println("No value");
        }
    
        System.out.println();
    
        Optional<Integer> resultOfFindFirst2 = testResultList
                .stream()
                .parallel()
                .findFirst();
    
        if(resultOfFindFirst2.isPresent()) {
            System.out.println("resultOfFindFirst2: " + resultOfFindFirst2);
            System.out.println("resultOfFindFirst2.get(): " + resultOfFindFirst2.get());
        } else {
            System.out.println("No value");
        }
    
     

    출력 결과는 어떨까요?

    아래와 같습니다.

    resultOfFindFirst: Optional[1]
    resultOfFindFirst.get(): 1
    
    resultOfFindFirst2: Optional[1]
    resultOfFindFirst2.get(): 1
     

    헉...! 분명 parallel 메소드를 사용하였지만 순서를 보장해 줍니다....!!

    저는 그래서 병렬처리와 더불어 순서가 중요할 때는 findFirst(), 순서가 중요하지 않을 때에는 findAny()를 사용합니다. 어떻게 도움이 되셨을지 모르겠습니다. 아는 게 많지 않다 보니...

     

    아무쪼록 긴 글 읽어주셔서 감사드리고 다음 시간에는 map을 list로, list를 map으로 쉽게 변환하는 법에 대해서 알아볼게요.

     

    감사합니다!

     

    댓글

Designed by Tistory.