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);
}
}
감사합니다.