본문 바로가기
자바

Stream & Optional & Parallel Stream

by 이상한나라의개발자 2023. 12. 12.

아래 코드는 특정 숫자를 비교하여 출력및 예외를 던지는 코드입니다.

1234를 비교 하기때문에 RuntimeException이 발생하게 됩니다.

 

public class ForAndIfFilterExampleMain {
    public static void main(String[] args) {
        List<Integer> integerList = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        Integer findNumber = null;

        for (int i = 0; i < integerList.size(); i++) {
            if(integerList.get(i).equals(1234)) {
                findNumber = integerList.get(i);
                break;
            }
        }

        if(findNumber == null)
            throw new RuntimeException();

        System.out.println("findNumber=" + findNumber);
    }
}

 

stream optional 사용

 

위 코드와 비교해서 어떤 코드가 더 가독성이 좋은지 확인 해봅시다.

 

public class ForAndIfFilterOptionalExampleMain {
    public static void main(String[] args) {
        List<Integer> integerList = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        Integer integer1 = integerList.stream()
                .filter(integer -> {
                    return integer.equals(1234);
                })
                .findAny() // optional 반환 (값이 없을 수도 있음)
                .orElseThrow(); // NoSuchElementException 발생

        System.out.println("integer1 = " + integer1);
    }
}

 

 

좀더 구체적인 예제

 

public class User {
    private String id;
    private String name;

    public User() {
    }

    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public boolean isSame(String id) {
        return this.id.equals(id);
    }
}


public class ForAndIfFilterAdvanceExampleMain {

    public static void main(String[] args) {
        User user1 = new User("a", "name1");
        User user2 = new User("b", "name2");

        List<User> users = List.of(user1, user2);

        users.stream()
                .filter(user -> user.isSame("c"))
                .findAny()
                .ifPresentOrElse(
                        user -> System.out.println("user = " + user),
                        () -> System.out.println("user is not found"));

    }
}

 

 

Stream API는 for문 보다 느린가?

경우에 따라 다르지만, 실제로 느릴 수 있다. 하지만 가독성 우선하여 개발 후 성능이 필요한 경우 튜닝 하는게 좋겠습니다.

 

 

Parallel Stream

 

Parallel Stream은 Java 8의 Stream API에 속하며, 데이터를 병렬로 처리하여 성능 향상을 꾀할 수 있게 도와줍니다. 주로 멀티 코어 프로세서의 환경에서 여러 코어를 활용해 데이터를 병렬로 처리하게 됩니다.

 

일반적인 스트림은 데이터를 순차적으로 처리하는 반면, 병렬 스트림은 데이터를 여러 조각으로 나누어 동시에 처리하게 됩니다. 이로써 큰 데이터셋이나 시간이 오래 걸리는 연산에서 성능의 향상을 기대할 수 있습니다.

 

기존 스트림을 병렬 스트림으로 변환하는 것은 매우 간단합니다. parallel() 메서드를 사용하면 됩니다.

 

List<String> list = Arrays.asList("A", "B", "C", "D");

// 병렬 스트림으로 변환
Stream<String> parallelStream = list.parallelStream();

 

 

주의점

 

병렬 스트림은 무조건 성능이 향상된다는 보장이 없습니다. 몇 가지 주의점이 있습니다:

작은 데이터셋에는 적합하지 않을 수 있습니다. 병렬 처리를 위한 오버헤드가 순차 처리보다 더 클 수 있기 때문입니다.

병렬 스트림에서는 순서를 보장받지 못할 수 있습니다. 순서에 의존적인 연산을 수행할 때는 주의가 필요합니다.

스레드-세이프하지 않은 연산이나 자료구조를 사용할 때 문제가 발생할 수 있습니다. 병렬 스트림을 사용할 때는 연산이나 자료구조가 여러 스레드에서 동시에 안전하게 동작하는지 확인해야 합니다.

 

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 순차 스트림
int sum = numbers.stream().reduce(0, Integer::sum);

// 병렬 스트림
int parallelSum = numbers.parallelStream().reduce(0, Integer::sum);

'자바' 카테고리의 다른 글

static  (0) 2023.12.13
자바 메모리 구조  (0) 2023.12.13
Stream  (0) 2023.12.12
슬기롭게 주석 사용하기  (0) 2023.12.12
순회 하면서 컬렉션 수정하지 않기  (0) 2023.12.12