스트림이 익숙해지지 않아서 정리해본다. for문을 계속 돌리면서 약간 자괴감이 느껴지기 때문에 확실히 정리 해두는 것이 필요 할 것 같다.
참조
https://futurecreator.github.io/2018/08/26/java-8-streams/
https://mangkyu.tistory.com/112?category=872426
Iterator
와 비슷하지만 코드가 좀 더 간결하고 병렬 처리가 쉬움Stream
요소들에서 처리 된다.list.stream() // 생성하기
.filter(s -> s.startWith("c")) // 가공하기
.map(String::toUpperCase) // 가공하기
.sorted() // 가공하기
.count() // 결과 만들기
Arrays.stream
메소드를 이용해서 접근
Car[] cars = new Car[] {"min", "choi", "test"};
Stream<Stream> stream = Arrays.stream(arr); // stream 생성
stream.forEach(car -> System.out.println(car));
해당 컬렉션 인터페이스에 구현되어 있는 stream
메소드를 이용해서 만들 수 있음
List<Car> cars = Arrays.asList("min", "choi", "test");
Steam<String> stream = list.stream();
builder
를 사용하여 스트림에 직접 원하는 값을 넣을 수 있음
Stream<String> stream =
Stream.<String>builder()
.add("min").add("choi").add("java")
.build();
병렬 스트림을 쉽게 생성하기 위해서 Stream
대신 parallelStream
메소드를 사용함
쓰레드를 이용하여 병렬 처리 됨
cars
.parallelStream() // 생성하기
.map()
.anyMatch()
int, long, double과 같은 원시 자료형을 사용하기 위한 스트림(IntStream, LongStream, DoubleStream)들을 사용 할 수 있음
IntStream stream = IntStream.range(4, 10); // for문 대신
스트림 내의 요소들을 하나씩 걸러내는 작업
조건에 맞는 데이터만을 가져와서 더 작은 컬렉션을 만들어내는 연산
Stream<T> filter(Predicate<? super T> predicate); // boolean 값을 return하는 Predicate 함수형 인터페이스를 매개 변수로 받음
기존의 Stream 요소들을 변환하여 새로운 Stream을 형성하는 연산
저장된 값을 특정한 형태로 변환하는데 주로 사용함 > 스트림에 저장되어 있는 값이 특정 로직을 거친 후 특정한 형태로 변환되는 연산
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
// Example, 대문자로 변환한 값들이 stream에 담기게 됨
Stream<String> stream =
names
.stream() // 생성
.map(String::toUpperCase); // 가공하기
Stream<Integer> stream =
products
.stream()
.map(Product::getAmount()); // Product.getAmount(); 값을 stream으로 맵핑(?)
Stream<T> sotred();
Stream<T> sorted(Comparator<? super T> comparator);
Stream<String> stream =
list
.stream() // 생성
.sorted() // 정렬
Stream<String> stream =
list
.stream() // 생성
.sorted(Comparator.reverseOrder()) // 정렬
.collect(Collectors.toList());
Stream<String> stream =
list
.stream() // 생성
.distinct() // 중복 제거
Stream에 영향을 주지 않고 특정 연산을 수행한다.
Consumer 함수형 인터페이스를 인자로 받는다.
IntStream.of(1,3,5,7,9)
.peek(System.out::println)
.sum()
Stream 객체를 원시 Stream으로 바꾸거나 원시 Stream을 Stream 객체로 바꿔야 함
mapToInt()
, mapToLong()
, mapToDouble()
, mapToObject
// IntStream (원시Stream) > Stream<Integer>
IntStream
.range(1,4)
.mapToObj(i -> i+1);
// Stream<Double> > IntStream > Stream<String>
Stream.of(1.0, 2.0, 3.0)
.mapToInt(Double::intValue)
.mapToObj(i -> "test" + i);
max, min, average의 경우 Stream이 비어있는 경우에는 값을 줄 수 없기 때문에 Optional로 값이 반환된다.
데이터 수집
Stream 요소들을 List, Set, Map과 같이 다른 종류의 결과로 수집하고 싶은 경우 사용
List<Car> cars = Arrays.asList(
new Car(1000, "min"),
new Car(2000, "choi"),
new Car(3999, "test"));
// 원래의 코드라면
List list = new ArrayList();
for (Car car : cars) {
car.add(list);
}
// stream을 사용해서 멋지게 리스트로 받을 수 있다.
List<String> names = cars
.stream()
.map(Car::getName)
.collect(Collectors.toList());
// result: <min, choi, test>
String names = cars
.stream()
.map(Car::getName)
.collect(Collectors.joining(",", "<", ">");
Integer priceSum = cars
.stream()
.collect(Collectors.summingInt(Car::getPrice));
Stream의 요소들이 특정한 조건을 충족하는지 검사하고 싶은 경우 match 함수를 이용한다
Predicate 함수형 인터페이스를 받아 해당 조건을 만족하는 요소가 있는지 결과를 리턴 함.
anyMatch
: 하나라도 조건을 만족하는 요소가 있는지 확인 함allMatch
: 모두 조건을 만족하는지 확인 함noneMatch
: 모두 조건을 만족하지 않는지 확인 함boolean anyMatch(Predicate<? super T> predicate);
boolean allMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);
boolean anyMatch = list
.stream()
.anyMatch(name -> name.contains("min"));