자료를 다루기 위한 스트림
- 한번 생성하고 사용한 스트림은 재사용할 수 없음
- Collection들은 다 스트림 호출 가능함
중간 연산과 최종 연산
sList.stream().filter(s->s.length() >= 5).forEach(s->System.out.println(s));
- filter()가 중간 연산, forEach가 최종연산
- 최종 연산이 호출 될 때 중간 연산이 수행되고 결과가 생성 됨(lazy Evaluation)
- 아래와 같이 구현하면, map.filter.foreach 할 때마다 MyCollection이 새로 생성되지만, stream으로 똑같이 구현하면 하나 하나의 값에 대해서 연산이 수행되고, 필요한 시점까지 기다렸다가 연산 수행(lazy evaluation)
public class MyCollection<T> {
private List<T> list;
public MyCollection(List<T> list){
this.list = list;
}
public <R> MyCollection<R> map(Function<T, R> function){
List<R> newList = new ArrayList<>();
foreach(d -> newList.add(function.apply(d)));
return new MyCollection<>(newList);
}
public void foreach(Consumer<T> consumer){
for(T ele : list){
consumer.accept(ele);
}
}
public MyCollection<T> filter(Predicate<T> predicate){
List<T> filteredList = new ArrayList<>();
foreach(d -> {
if(predicate.test(d)){
filteredList.add(d);
}
});
return new MyCollection<>(filteredList);
}
}
스트림 생성 & 활용
다양한 변환
Stream<Integer> s = Arrays.asList(1, 2, 3).stream();
IntStream s2 = Arrays.stream(new int[]{1, 2, 3}) // IntStream 같은 것은 primitive type
// 을 위한 stream임
// stream -> list
List<Integer> s3 = s2.boxed().toList();
// primitive stream -> wrapper stream
Stream<Integer> s3 = s2.boxed();
// wrapper stream -> primitive stream
IntStream intStream = s1.mapToInt(i -> i);
// wrapper stream -> wrapped Array
s3.toArray(Integer[]::new);
// premitive stream -> premitive Array
int[] arr = s2.toArray(); // 따로 생성자 new 안해주어도 됨
Stream.generate()
Stream.generate(() -> 1).forEach(System.out::println); // 1이 계속 프린트됨. 끝없이
Stream.generate(() -> 1).limit(10).forEach(System.out::println);
Stream.iterate()
Stream.iterate(0, (i) -> i + 1).forEach(System.out::println); // 0에서부터 출발해서
// 1씩 더하는 값 계속해서 출력함
FlatMap
public List<Account> getAccountsByOrganizationId(Integer organizationId) {
List<Department> departments = departmentService.getByOrganizationId(
organizationId);
List<Account> accounts = departments.stream()
.map(department -> accountRepository.findByDepartmentId(department.getId()))
.flatMap(accountList -> Arrays.stream(accountList.toArray(new Account[0])))
.toList();
accountRepository.findByDepartmentId()
}
- map에서 input과 output이
Department
→ List<Account>
이므로, List<List<Account>> 가 아닌, List<Account>로 해당 결과값을 펼쳐서 하나의 리스트로 만드려고 하는 것이 목적