반응형
먼저 Product 는 item 리스트를 갖고 있다(Product 는 여러개일 수 있다).
@Value
@Builder
public class Product {
List<Item> items;
}
item 은 id 필드만 존재한다.
@Value
@Builder
public class Item {
String id;
}
이제 각 Product 안의 모든 Item id 를 검사하는 로직을 만들어보자. 그런데 2가지 조건이 있다.
1. 모든 Item 들을 다 검사하고, 실패하는 것들은 예외 리스트로 담아서 전달.
2. 예외 객체에 담을 때 item index 정보가 필요.
index 정보가 필요하니 가장 먼저 생각나는것은 고전 for문 방식이다. 이중 for문 으로 각 Product 안의 모든 Item 을 검사하고 예외가 발생하면 catch 에서 리스트로 담아 리턴하는 코드다. 간단하고 직관적이다(이 방식이 더 좋다고 느껴질때도 있다).
private static List<CheckException> method1(List<Product> products) {
List<CheckException> exceptions = new ArrayList<>();
for (Product eachProduct : products) {
List<Item> items = eachProduct.getItems();
for (int itemIndex = 0; itemIndex < items.size(); itemIndex++) {
try {
checkItem(items.get(itemIndex), itemIndex);
} catch (CheckException ex) {
exceptions.add(ex);
}
}
}
return exceptions;
}
private static void checkItem(Item item, int itemIndex) {
if (item.getId().equals("")) {
throw new CheckException(itemIndex);
}
}
두번째 방법은 stream 을 활용한다. product 리스트 객체에서 stream 을 시작했으니 flatMap 을 사용해야 한다.
cf) 만약 map 을 사용하면 List<Stream<CheckException>> type 이 되버린다.
그리고 index 정보를 checkItem 메서드에 전달하기 위해 IntStream.range 를 사용한다. 또 mapToObj 안에서 검사를 정상통과하면 null을 리턴, 예외가 발생하면 예외객체를 리턴시키고 null 이 아닌것만 filter 시켜 리스트로 만든다.
private static List<CheckException> method2(List<Product> products) {
return products
.stream()
.flatMap(eachProduct -> {
List<Item> items = eachProduct.getItems();
return IntStream.range(0, items.size())
.mapToObj(itemIndex -> {
try {
checkItem(items.get(itemIndex), itemIndex);
return null;
} catch (CheckException ex) {
return ex;
}
})
.filter(Objects::nonNull);
})
.toList();
}
두번째 방법이 무조건 좋다고 생각하진 않지만, 다른 방법도 있다는걸 기록하는 차원에서 작성했다.
반응형
'Java' 카테고리의 다른 글
Enum 타입 에 따른 테스트(DynamicTest) (0) | 2023.02.18 |
---|---|
자바로 같은 상품 Grouping (0) | 2023.02.05 |
자바 Function.andThen 과 apply 작동 순서 (0) | 2022.08.30 |
함수형 파라미터를 두번 전달하는 이슈 정리 (0) | 2022.01.05 |
날짜 포맷 하위호환(기록용) (0) | 2022.01.04 |