전체 -> 맵핑 -> 필터링 1 -> 필터링 2 -> 결과 만들기 -> 결과물
Stream, Stream 과 같은 것들
자바 스트림 API는 숫자 스트림을 효율적으로 처리할 수 있도록 세 가지 기본형 특화 스트림을 제공한다.
IntStream, DoubleStream, LongStream
| 종류 | 데이터형 | 크기(byte / bit) |
|---|---|---|
| 논리형 | boolean | 1 / 8 |
| 문자형 | char | 2 / 16 |
| 정수형 | byte | 1 / 8 |
| 정수형 | short | 2 / 16 |
| 정수형 | int | 4 / 32 |
| 정수형 | long | 8 / 64 |
| 실수형 | float | 4 / 32 |
| 실수형 | double | 8 / 64 |
이러한 특화 스트림은 숫자 스트림의 합계를 계산하는 sum, 최댓값 요소를 검색하는 max 같이 자주 사용하는 숫자 관련 리듀싱 연산 수행 메서드를 제공한다!
mapToInt, mapToDouble, mapToLong 메서드를 이용하면 일반 스트림을 특화 스트림으로 변환할 수 있다.
int totalPayPrice = pays.stream()
.mapToInt(Pay::getPayPrice)
.sum();
💡 저 :: 은 도대체 뭘까?
자바의 메소드 레퍼런스라는 것으로, 람다식을 다른 방식으로 표현한 것이다.
예
람다식 (text)-> System.out.println(text)
메소드 레퍼런스 System.out :: println
메소드 레퍼런스는 [ClassName] :: [MethodName] 형식으로 입력하고,
메소드를 호출하는 것이지만 괄호()는 써주지 않고 생략한다!
.mapToInt(Pay::getPayPrice)
람다식로 변환하면?
.mapToInt(onePay → onePay.getPayPrice)
List를 int[]로 변환하고 싶다면?
mapToInt이용!
int[] arr = list.stream()
.mapToInt(i -> i) // == mapToInt(Integer::intValue)
.toArray();
boxed() 메서드는 IntStream 같이 원시 타입에 대한 스트림 지원을 클래스 타입(예: IntStream -> Stream<Integer>) 으로 전환해준다.
사용 예: int 자체로는 Collection에 못 담기 때문에 Integer 클래스로 변환하여 List<Integer> 로 담기 위해 사용한다.
List<Integer> list1 = Arrays.stream(arr) // == IntStream.of(arr)
.boxed()
.collect(Collectors.toList());

if문이라고 생각하면 편하다.
일치하는 모든 요소를 포함하는 스트림으로 반환한다.
메뉴 List에서 베지테리안 메뉴만 찾아서 리스트로 저장하고 싶다면?
List<Dish> vegetarianMenu = menu.stream()
.filter(Dish::isVegetarian) // 리턴값이 true면 다음 단계 진행, false면 버려짐!
.collect(Collectors.toList());
스트림의 요소들을 우리가 원하는 자료형으로 변환할 수 있다.
toList(), toSet(), toMap(), toCollection()
stream.collect(Collectors.toSet()); //set으로 변환
stream.collect(Collectors.toList()); //list 변환
stream.collect(Collectors.joining()); //요소를 다 이어붙여서 하나의 string으로 변환
stream.collect(Collectors.joining(", ")); //요소들 사이에 ","을 넣어서 한개의 string 반환
List나 Set이 아닌 특정 컬렉션을 지정하려면 toCollection() 에 해당 컬렉션의 생성자 참조를 매개변수로 넣어주면 된다.
ArrayList<String> list = names.stream()
.collect(Collectors.toCollection(ArrayList::new));
stream.toArray() 사용!Person[] personArray1 = personStream1.toArray(Person[]::new);
스트림을 우리가 원하는 모양의 새로운 스트림으로 변환할 수 있다.
스트림 내 문자열을 모두 대문자로 변경한 스트림 만들기?
Stream<String> stream = names.stream()
.map(String::toUpperCase);
anyMatchallMatchnoneMatchList<String> names = Arrays.asList("Eric", "Elena", "Java");
boolean anyMatch = names.stream()
.anyMatch(name -> name.contains("a"));
boolean allMatch = names.stream()
.allMatch(name -> name.length() > 3);
boolean noneMatch = names.stream()
.noneMatch(name -> name.endsWith("s"));
결과는 모두 true!
1.int[] numbers = {1, 2, 3, 4, 5};
위와 같은 배열이 있을 때,
스트림을 활용해서 아래와 같은 동작을 수행하자!
1. 홀수만 골라서, → filter()
2. 2를 곱한 뒤, → map()
3. 배열에 저장한다. → toArray
int[] result = Arrays.stream(numbers)
.filter(num -> num % 2 == 1)
.map(num-> num * 2) -> 스트림
.toArray();
2.int[] data = {5, 6, 4, 2, 3, 1, 1, 2, 2, 4, 8};
위와 같은 배열이 있을 때,
스트림을 활용해서 아래와 같은 동작을 수행하자!
1. 짝수만 뽑은 뒤, → filter
2. 중복을 제거하고, →
3. 역순으로 정렬해서 →
4. 출력한다. → foreach
Arrays.stream(data)
.boxed() // IntStream에서 -> Stream<Integer>로 변환
.filter(n -> n % 2 == 0)
.distinct() // 중복 제거
.sorted(Comparator.reverseOrder())
.forEach(System.out :: println); // == .forEach((num) -> System.out.println(num))
boxed 하는 이유?sorted(Comparator.reverseOrder())를 하기 위함.sorted()는 내림차순이 불가능!!3.프로그래머스 음양 더하기
class Solution {
public int solution(int[] absolutes, boolean[] signs) {
int sum = 0;
for(int i=0; i<absolutes.length; i++) {
if(!signs[i]) {
absolutes[i] *= -1;
}
sum += absolutes[i];
}
return sum;
}
}
스트림 활용 리팩토링
import java.util.stream.IntStream;
class Solution {
public int solution(int[] absolutes, boolean[] signs) {
int sum = IntStream.range(0, absolutes.length)
.map(i -> !signs[i] ? -absolutes[i] : absolutes[i])
.sum();
return sum;
}
}