개념
특징
과정
배열 스트림 : Arrays.stream()
String [] arr = new String[]{"a","b","c"};
Stream<String> stream = Arrays.stream(arr);
컬렉션 스트림: .stream()
List<String> list = Arrays.asList("a", "b" ,"c");
Stream<String> stream = list.stream()
Stream<String> builderStream = Stream.<String>builder()
.add("a").add("b").add("c")
.build();
Stream<String> generatedStream = Stream.generate(() -> "a").limit(3);
// 생성할 때 스트림의 크기가 정해져있기 않기(무한하기) 때문에 최대 크기를 제한해줘야 한다.
Stream<Integer> iteratedStream = Stream.iterate(0, n -> n + 2).limit(5); //0,2,4,6,8
IntStream intStream = IntStream.range(1, 5); // [1, 2, 3, 4]
병렬 스트림
Stream<String> parallelStream = list.parallelStream();
지연 연산
findMembers.stream()
.map(m -> {
System.out.println("mapping: " + m.getName());
return new MemberDTO(m.getName());
}) //중간 연산
.collect(Collectors.toList());
map은 스트림내 요소들에 대해 함수가 적용된 결과의 새로운 요소로 변환한다.
예시
Stream<String> names = Stream.of("kim","lee");
Stream<Integer> lengths =names.map(s -> s.length()).toList(); //문자열 -> 길이로 변환
“kim” → 3 , “lee” → 3, “park” → 4
즉, map 은 요소를 고르는 게 아니라, 요소를 바꾸는 연산
중간 연산
Filtering
List<String> list = Arrays.asList("a","b","c");
Stream<String> stream = list.stream()
.filter(list -> list.contains("a"));
// a 가 들어간 요소만 선택 [a]
Mapping
Stream<String> stream = list.stream()
.map(String:: toUpperCase);
//[A, B, C]
.map(Integers::parseInt);
//문자열 -> 정수로 변환
Sorting
Stream<String> stream = list.stream()
.sorted() //[a, b, c] 오름차순
.sorted(Comparator.reverseOrder()) //[c, b, a] 내림차순
List<String> list = Arrays.asList("a","bb","ccc");
Stream<String> stream = list.stream()
.sorted(Comparator.comparingInt(String::length)) // [ccc, bb, a] 문자열 길이 기준 정렬
최종 연산 (결과 만들기)
Calculating
IntStream stream = list.stream
.count() //스트림 요소 개수 반환
.sum() //스트림 요소의 합 반환
.min() //스트림의 최솟값 반환
.max() // 스트림의 최대값 반환
.average() //스트림의 평균값 반환
Reduction
IntStream stream = IntStream.renge(1,5);
.reduce(10, (total, num) -> total + num);
Collecting
List<Person> members = Arrays.asList(new Person("lee",26),new Person("kim", 23), new Person("park", 23));
// toList() - 리스트로 반환
members.stream()
.map(Person::getLastName)
.collect(Collectors.toList());
//[lee, kim, park]
// joining() - 작업 결과를 하나의 스트링으로 이어 붙이기
members.stream()
.map(Person:: getLastName)
.collect(Collectors.joining(delimiter = "+", prefix = "<" , suffix = ">");
//<lee+kim+park>
//groupingBy() - 그룹지어서 Map으로 반환
members.stream
.collect(Collectors.groupingBy(Person::getAge));
)
// {26 = [Person{lastName="lee",age=26}],
// 23 = [Person{lastName="kim",age=23},Person{lastName="park",age=23}]}
members.stream
.collect(Collectors.collectingAndThen(Collectors.toSet(),Collections::unmodifiableSet));
Matching
특정 조건을 만족하는 요소가 있는지 체크한 결과를 반환
List<String> members = Arrays.asList("Lee", "Park", "Hwang");
boolean matchResult = members.stream()
.anyMatch(members -> members.contains("w")); //w를 포함하는 요소가 있는지, TRUE
boolean matchResult = members.stream()
.anyMatch(members -> members.length() >= 4 );
//모든 요소의 길이가 4 이상인지, False
boolean matchResult = members.stream()
.anyMatch(members -> members.endsWith("t"));
//t로 끝나는 요소가 하나도 없는지, true
Iterating
members.stream()
.map(Person :: getName)
.forEach(System.out::println);
//결과를 출력 (peek는 중간, forEach는 최종)
Finding
Person person = members.stream()
.findAny() //먼저 찾은 요소 하나 반환, 병렬 스트림의 경우 첫번째 요소가 보장되지 않음
.findFirst() //첫번째 요소 반환