자바로 다시 사용하면서 너무 for문에 익숙함, stream의 사용예제를 적고 사용하도록 노력하자.
stream을 사용해서 List<List<Integer>> → List<Lotto> 로변경
// 변경 전
public static Lottos fromManualLottos(List<List<Integer>> manualLottos) {
List<Lotto> lottos = new ArrayList<>();
for (int i = 0; i < manualLottos.size(); i++) {
lottos.add(Lotto.fromManualLotto(new LottoPolicyStrategy(), manualLottos.get(i)));
}
return new Lottos(lottos);
}
// 변경 후
public static Lottos fromManualLottos(ManualLottoParam manualLotto) {
List<Lotto> lottos = manualLotto.getManualLottos()
.stream()
.map(numbers -> Lotto.fromManualLotto(new LottoPolicyStrategy(), numbers.getLottoNumbers()))
.collect(Collectors.toList());
return new Lottos(lottos);
}
Java
복사
stream을 사용해서 List를 Map 으로 변경
private Map<Integer, Integer> convertLottoNumbersToMap(Lotto winningLotto) {
return winningLotto.getNumbers()
.stream()
.collect(Collectors.toMap(LottoNumber::getNumber, LottoNumber::getNumber));
}
Java
복사
Duplicate Key Error 방지 Function.identity() 함수를 사용
Map<Long, Object> memberMapData = new HashMap<>();
List<Member> members = MemberRepository.getMemberList();
if (CollectionUtils.isNotEmpty(members)) {
memberMapData = members.stream()
.collect(Collectors.toMap(Member::getMemberId, Function.identity()));
}
Java
복사
List를 스트림을 써서 Map으로 변경하는데, key = id 로받고, 해당하는 객체를 그대로 쓰기위해 Function.identity를 사용.
stream을 사용해서 enum 값 찾기
return Arrays.stream(values())
.filter(value -> rank == value.rank)
.findFirst()
.orElse(WinningAmountByRank.EMPTY);
Java
복사
stream을 사용해서 list 값 합치기
public double calculatorProfit(Lottos lottos, int purchaseAmount) {
double sum = lottos.getLottos()
.stream()
.mapToInt(lotto -> WinningAmountByRank.from(getWinningResult(lotto)).getAmount()).sum();
return sum / purchaseAmount;
}
Java
복사
stream을 사용해 중복값 체크
if(manualLottoNumbers.size() != manualLottoNumbers.stream()
.distinct()
.count()){
throw new IllegalArgumentException("중복 값이 있습니다.");
}
Java
복사
stream의 null check
1.
Null 자체가 Stream이 되면 NPE 가 발생한다.
2.
Null 일경우 emptyCollection 리턴.
3.
Null 일경우 emptyList를 리턴.
List<Member> members = null;
//error
members.stream().filter(Objects::nonNull).forEach(
Object -> System.out.println(Object::getUsername));
//ok
CollectionUtils.emptyIfNull(members).stream()
.filter(("coby").equals(Object::getUsername())).collect(Collectors.toList());
//ok
Optional.ofNullable(members)
.orElseGet(Collections::emptyList).stream()
.filter(("coby").equals(Object::getUsername())).collect(Collectors.toList())
Java
복사
emptyIfNull 함수 설계 빈 값일시 emptyCollection을 리턴한다.
// CollectionUtils 클래스
public static <T> Collection<T> emptyIfNull(Collection<T> collection) {
return collection == null ? emptyCollection() : collection;
}
Java
복사
컬렉션의 값을 체크할때 CollectionUtils 클래스를 애용하자.
// CollectionUtils 클래스
// 널과 함께, 값을 체크한다.
public static boolean isEmpty(Collection coll) {
return coll == null || coll.isEmpty();
}
public static boolean isNotEmpty(Collection coll) {
return !isEmpty(coll);
}
Java
복사
stream으로 List값 String으로 합치기
String victoryMessage = winners.stream().map(n -> String.valueOf(n.getName()))
.collect(Collectors.joining(", "));
Java
복사
reduce 사용법
List에 담긴 모든 숫자의 합을 구한다.
// nextstep.fp.StreamStudy 클래스의 sumAll method 참고
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
public int sumAll(List<Integer> numbers) {
return numbers.stream().reduce(0, (x, y) -> x + y);
}
Java
복사
리듀스에 잘 설명한 블로그가 있어서 참조하도록 하겠다.