Java

[기초문법] Java8 Stream 적용/미적용 실습해보기

chandlerxx 2024. 1. 16. 11:43

자바 문법을 활용하면 코드의 가독성을 높이는 효과도 있습니다. Java8부터 추가된 기능Stream()에 대해 알아보겠습니다.

 

Tip) 

자바 api문서는 여기를 참고해주세요
구글링하시면 다른 블로그에서도 충분한 설명이 되어 있으니 참고해주세요.

 

 

1. 결론


 

  • 'Stream'
    • 도입 전 : 반복문(for)을 통해서 데이터를 하나씩 가공 처리  
    • 도입 후 : 람다형식으로 쉽게 처리 
  • 장점
    • 코드가 간결해짐
    • 성능 측면에서도 유리

 

 

2. 코드비교 


여기 코드 참고해주세요.

깃허브에 코드는 올려뒀습니다.

 

상황

  • Custom 클래스 : 손님 이름과 복지 포인트 변수를 담고 있음
  • 복지 포인트가 100점 이상인 손님 정보가 필요함

 

<Customer 클래스>

@Getter
public class Customer {

    private String name;
    private int points;
    
    public Customer(String name, int points) {
        this.name = name;
        this.points = points;
    }

}

 

 

<Stream 적용 안된 경우>

굉장히 번거로운 작업임을 확인할 수 있습니다

  • 전체 손님 정보를 포함한 컬렉션 `customers` 생성
  • 그중에서 포인트100점 이상인 손님만 필터링하기 위해 반복문과 if문 사용 
  • 추가로 별도의 customersOverHundredPoints 객체 생성 필요
    @Test
    @DisplayName("복지포인트100점 이상인 손님_불러오기")
    void test() {
        //given
        Customer john = new Customer("John P.", 15);
        Customer sarah = new Customer("Sarah M.", 200);
        Customer charles = new Customer("Charles B.", 150);
        Customer mary = new Customer("Mary T.", 1);

        List<Customer> customers = Arrays.asList(john, sarah, charles, mary);

	//when
        List<Customer> customersOverHundredPoints = new ArrayList<>();

        for (Customer customer : customers) {
            if (customer.getPoints() > 100) {
                customersOverHundredPoints.add(customer);
            }
        }
        
        //then
        assertEquals(customersOverHundredPoints.get(0).getName(), "Sarah M.");
        assertEquals(customersOverHundredPoints.get(0).getPoints(), 200);
        assertEquals(customersOverHundredPoints.get(1).getName(), "Charles B.");
        assertEquals(customersOverHundredPoints.get(1).getPoints(), 150);
    }

 

 

 

 

<Stream 적용된 경우>

  • 반복문과 if문이 없어지고 lambda 표현식으로 간결하게 처리 가능
    @Test
    @DisplayName("복지포인트100점 이상인 손님_불러오기_stream적용")
    void test2() {
        //given
        Customer john = new Customer("John P.", 15);
        Customer sarah = new Customer("Sarah M.", 200);
        Customer charles = new Customer("Charles B.", 150);
        Customer mary = new Customer("Mary T.", 1);

        List<Customer> customers = Arrays.asList(john, sarah, charles, mary);

        //when
        List<Customer> customersOver100Points = customers.stream()
                .filter(c -> c.getPoints() > 100)
                .collect(Collectors.toList());

        //then
        assertEquals(2, customersOver100Points.size());
        assertEquals(customersOver100Points.get(0).getName(), "Sarah M.");
        assertEquals(customersOver100Points.get(0).getPoints(), 200);
        assertEquals(customersOver100Points.get(1).getName(), "Charles B.");
        assertEquals(customersOver100Points.get(1).getPoints(), 150);
    }

 


 

추가로 코드를 개선한다고 하면, `@Builder`패턴을 적용하면, 코드가 보다 명확해지겠네요.

 

@Getter
public class Customer {

    private final String name;
    private final int points;

    @Builder
    public Customer(String name, int points) {
        this.name = name;
        this.points = points;
    }
    
    public boolean hasOverHundredPoints() { // 메서드 추가
        return this.points > 100;
    }
}

 

    @Test
    @DisplayName("복지포인트100점 이상인 손님_불러오기_stream적용")
    void test2() {
        //given
        Customer john = Customer.builder()
                .name("John P.")
                .points(15)
                .build();

        Customer sarah = Customer.builder()
                .name("Sarah M.")
                .points(200)
                .build();

        Customer charles = Customer.builder()
                .name("Charles B.")
                .points(150)
                .build();

        Customer mary = Customer.builder()
                .name("Mary T.")
                .points(1)
                .build();

        List<Customer> customers = Arrays.asList(john, sarah, charles, mary);

        //when
        List<Customer> customersOver100Points = customers.stream()
                .filter(c -> c.hasOverHundredPoints())
                .collect(Collectors.toList());

        //then
        assertEquals(2, customersOver100Points.size());
        assertEquals(customersOver100Points.get(0).getName(), "Sarah M.");
        assertEquals(customersOver100Points.get(0).getPoints(), 200);
        assertEquals(customersOver100Points.get(1).getName(), "Charles B.");
        assertEquals(customersOver100Points.get(1).getPoints(), 150);
    }

}

 

 

감사합니다.