스트림 문법
반환타입 | 메서드 |
boolean | allMatch(Predicate<? super T> predicate)
Returns whether all elements of this stream match the provided predicate.
|
boolean | anyMatch(Predicate<? super T> predicate)
Returns whether any elements of this stream match the provided predicate.
|
static <T> Stream.Builder<T> | builder()
Returns a builder for a Stream.
|
<R,A> R | collect(Collector<? super T,A,R> collector) |
<R> R | collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner) |
static <T> Stream<T> | concat(Stream<? extends T> a, Stream<? extends T> b)
Creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.
|
long | count()
Returns the count of elements in this stream.
|
Stream<T> | distinct()
Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream.
|
static <T> Stream<T> | empty()
Returns an empty sequential Stream.
|
Stream<T> | filter(Predicate<? super T> predicate)
Returns a stream consisting of the elements of this stream that match the given predicate.
|
Optional<T> | findAny()
Returns an Optional describing some element of the stream, or an empty Optional if the stream is empty.
|
Optional<T> | findFirst()
Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty.
|
<R> Stream<R> | flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
|
DoubleStream | flatMapToDouble(Function<? super T,? extends DoubleStream> mapper)
Returns an DoubleStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
|
IntStream | flatMapToInt(Function<? super T,? extends IntStream> mapper)
Returns an IntStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
|
LongStream | flatMapToLong(Function<? super T,? extends LongStream> mapper)
Returns an LongStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
|
void | forEach(Consumer<? super T> action)
Performs an action for each element of this stream.
|
void | forEachOrdered(Consumer<? super T> action)
Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order.
|
static <T> Stream<T> | generate(Supplier<T> s)
Returns an infinite sequential unordered stream where each element is generated by the provided Supplier.
|
static <T> Stream<T> | iterate(T seed, UnaryOperator<T> f)
Returns an infinite sequential ordered Stream produced by iterative application of a function f to an initial element seed, producing a Stream consisting of seed, f(seed), f(f(seed)), etc.
|
Stream<T> | limit(long maxSize)
Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.
|
<R> Stream<R> | map(Function<? super T,? extends R> mapper)
Returns a stream consisting of the results of applying the given function to the elements of this stream.
|
DoubleStream | mapToDouble(ToDoubleFunction<? super T> mapper)
Returns a DoubleStream consisting of the results of applying the given function to the elements of this stream.
|
IntStream | mapToInt(ToIntFunction<? super T> mapper)
Returns an IntStream consisting of the results of applying the given function to the elements of this stream.
|
LongStream | mapToLong(ToLongFunction<? super T> mapper)
Returns a LongStream consisting of the results of applying the given function to the elements of this stream.
|
Optional<T> | max(Comparator<? super T> comparator)
Returns the maximum element of this stream according to the provided Comparator.
|
Optional<T> | min(Comparator<? super T> comparator)
Returns the minimum element of this stream according to the provided Comparator.
|
boolean | noneMatch(Predicate<? super T> predicate)
Returns whether no elements of this stream match the provided predicate.
|
static <T> Stream<T> | of(T... values)
Returns a sequential ordered stream whose elements are the specified values.
|
static <T> Stream<T> | of(T t)
Returns a sequential Stream containing a single element.
|
Stream<T> | peek(Consumer<? super T> action)
Returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.
|
Optional<T> | reduce(BinaryOperator<T> accumulator)
Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.
|
T | reduce(T identity, BinaryOperator<T> accumulator)
Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value.
|
<U> U | reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
Performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions.
|
Stream<T> | skip(long n)
Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream.
|
Stream<T> | sorted()
Returns a stream consisting of the elements of this stream, sorted according to natural order.
|
Stream<T> | sorted(Comparator<? super T> comparator)
Returns a stream consisting of the elements of this stream, sorted according to the provided Comparator.
|
Object[] | toArray()
Returns an array containing the elements of this stream.
|
<A> A[] | toArray(IntFunction<A[]> generator)
Returns an array containing the elements of this stream, using the provided generator function to allocate the returned array, as well as any additional arrays that might be required for a partitioned execution or for resizing.
|
.allMatch( Predicate<? super T> predicate )
- 반환형이 boolean
- 따라서 추가적으로 메서드를 이어갈 수 없음
- 전부 일치하는가
boolean result = Arrays.stream(arr)
.allMatch(a -> a > 50);
Predicate
- 초기화 (함수형 인터페이스)
- https://toy-garden.tistory.com/101
- 즉 test(T t)를 람다식을 통해 호출함
new Predicate<T>() {
@Override
boolean test(T t){
}
}
Predicate<T> predicate = (t) -> 조건식
//ex)
Predicate<String> predicate = (str) -> str.startsWith("A");
new Predicate<String>() {
@Override
boolean test(String t){
return str.startWith("A");
}
} //이상태임
// 여기서 테스트 해보면
predicate.test("ABC"); //boolean 반환
- test(T t)
- 반환형이 boolean
- 즉 input argument t 가 true인지 false인지 반환
- and(), or()
- 두 Predicate를 이어줌
@Test
public void test() {
Predicate<Integer> predicate1 = (num) -> num < 10;
Predicate<Integer> predicate2 = (num) -> num > 5;
assertThat(predicate1.and(predicate2).test(7)).isTrue();
}
- negate()
- Predicate.test()의 결과와 반대로 return하는 Predicate 생성
@Test
public void test() {
Predicate<Integer> originPredicate = (num) -> num < 10;
Predicate<Integer> negatePredicate = originPredicate.negate();
assertThat(negatePredicate.test(5)).isFalse();
}
- isEqual()
import java.util.function.Predicate;
public class NumberEqualityCheck {
public static void main(String[] args) {
Predicate<Integer> isEqualToFive = Predicate.isEqual(5);
System.out.println(isEqualToFive.test(5)); // true 출력
System.out.println(isEqualToFive.test(10)); // false 출력
}
}
.anyMatch
- 반환형 boolean
- 하나라도 있나
boolean result = Arrays.stream(arr)
.anyMatch(a -> a > 50);
.noneMatch(Predicate<? super T> predicate)
- Boolean 반환
- 아무것도 일치하는게 없으면
.<T>builder()
- Stream Builder 반환
- 스트림을 최초 생성하는 T를 결정한다고 생각하면 됌
StreamBuilder
- accpet(T t)
- void를 반환
- add(T t)
- Stream.Builder를 반환
- 계속해서 이어서 추가할 수 있음
- build()
- 추가 완료 후 Stream을 다시 반환
.generate(Supplier<T> s)
- static <T> Stream<T> 반환
- generate로 생성되는 스트림은 크기가 정해져 있지 않고 무한하기 때문에 사이즈 제한을 해주어야 함
- .limit
Supplier<T>
- 매개변수 없이 반환값 만을 갖는 함수형 인터페이스
.iterate(T seed, UnaryOperator<T> f)
- static <T> Stream<T> 반환
- 무한하므로 사이즈 제한을 해주어야 함
- seed를 기준으로 f 연산을 하고 결과 값이 다시 들어가서 연산을 함)
UnaryOperator<T>
- Function과 달리 제네릭을 하나만 받음
- 항상 T 타입을 반환함
builder, generate, iterate
Stream<String> builderStream =
Stream.<String>builder()
.add("Eric").add("Elena").add("Java")
.build();
//output - [Eric, Elena, Java]
Stream<String> generatedStream =
Stream.generate(() -> "el").limit(5);
//output - [el, el, el, el, el]
Stream<Integer> iteratedStream =
Stream.iterate(30, n -> n + 2).limit(5);
//output - [30, 32, 34, 36, 38]
.filter(Predicate<? super T> predicate)
- 원하는 요소만 추출하기 위한 메서드
- Stream<T>반환
.map(Function<? super T, ? extends R> mapper)
- T를 인자로 받아 변환한 값 R을 반환하는 함수
- Stream<T> 반환
List<String> list = Arrays.asList("A", "B", "C", "D");
Stream<String> stream = list.stream()
.map(String::toLowerCase); // [a, b, c, d]
.mapToInt / .mapToLong / .mapToDouble
List<String> list = Arrays.asList("1", "2", "3", "4");
IntStream stream = list.stream()
.mapToInt(s -> Integer.parseInt(s)); // [1, 2, 3, 4]
.flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
- Stream<R> 반환
- 몇 차원의 배열을 단일 요소로 리턴해 처리함
String[][] namesArray = new String[][]{
{"kim", "taeng"}, {"mad", "play"}};
// flatMap
Arrays.stream(namesArray)
.flatMap(inner -> Arrays.stream(inner))
.filter(name -> name.equals("taeng"))
.forEach(System.out::println);
// map
Arrays.stream(namesArray)
.map(inner -> Arrays.stream(inner))
.forEach(names -> names.filter(name -> name.equals("taeng"))
.forEach(System.out::println));
// 위에는 kim taeng mad play로 처리가 됌
// map은 [kim taeng] [mad play] 형식이라 foreach로 둘을 각각 받아와서 필터링 해줘야 함
- flatMapToDouble > DoubleStream
- flatMapToInt > IntStream
- flatMapToLong > LongStream
.collect(Collector<? super T,A,R> collector)
- <R, A> R 반환
- T = 요소 / A = 누적기 / R = 저장될 컬렉션
- T요소를 A 누적기가 R에 저장한다
- Collectors 클래스의 정적 메소드 활용
.collect(Collectors.toSet());
.collect(Collectors.toList());
//위와 같은 방식으로 Collector를 받아와 실행 됌
.collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, r> combiner)
- <R> R 반환
Collectors
https://velog.io/@ehdrms2034/Java-8-Collector-%EC%A0%95%EB%A6%AC
.concat(Stream<? extends T> a, Stream<? extends T> b)
- static <T> Stream<T> 반환
- 스트림 합치기
public static void main(String args[]) {
List<Integer> intList1 = new ArrayList<>(Arrays.asList(10, 20, 30));
List<Integer> intList2 = new ArrayList<>(Arrays.asList(30, 40, 50));
Stream<Integer> intStream =
Stream.concat(intList1.stream(), intList2.stream());
intStream.forEach(System.out::println);
}
.count()
- long 반환
- 요소의 개수 반환
.distinct()
- Stream 반환
- 중복제거
.empty()
- static <T> Stream<T> 반환
- 빈 스트림 생성
.findAny() / .findFirst()
- Optional<T> 반환
- 실행할 때 마다 리턴값이 달라짐 / 항상 가장 앞 요소를 리턴
.forEach(Consumer<? super T> action) / .forEachOrdered(Consumer<? super T> action)
- void
- 요소를 돌면서 실행하는 최종 작업 / 병렬처리에서 순서를 보장할 때 사용
- 생각해봐야 할 점
- forEach는 모든 요소를 돌기 때문에 비효율적일 수 있음
- forEach 안의 람다에서 상태를 수정하지 말아야 함
- forEach 내부에 로직이 있으면 동시성 보장이 어려워지고 가독성이 떨어질 위험이 있음
- 결론 : stream().forEach()는 웬만하면 객체의 데이터를 다루지 말고 출력용으로만 사용
list.stream().forEach(System.out::println);
.limit(long maxSize)
- Stream 반환 / 길이 제한
.max(Comparator<? super T> comparator) / .min(Comparator comparator)
- Optional<T> 반환하기 때문에 이후 연결은 Optional 메서드를 사용해야 함
- 최대 / 최소
Optional
- null 체크
- empty()
- 빈 Optional 인스턴스를 리턴
- static <T> Optional<T> 반환
// Optional 메소드
Optional<String> empty = Optional.empty();
// 아웃풋
System.out.println(empty.isEmpty()); // true
- equals(Object obj)
- boolean 반환
- 기준 Optional instance와 obj에 들어갈 Optional instance를 비교함
// 인풋
Optional<String> opt1 = Optional.of("Hello");
Optional<String> opt2 = Optional.of("Hello");
Optional<String> opt3 = Optional.of("World");
// Optional 메소드
boolean isEqual1 = opt1.equals(opt2);
boolean isEqual2 = opt1.equals(opt3);
// 아웃풋
System.out.println(isEqual1); // true
System.out.println(isEqual2); // false
- filter(Predicate<? super T> predicate)
- stream과 같은 형식
- flatMap(~~)
- stream과 같은 방식인데 Optional을 넣음
- get()
- T 타입 반환
Optional<String> opt1 = Optional.ofNullable("Hello");
Optional<String> opt2 = Optional.ofNullable(null);
// 아웃풋
System.out.println(opt1.get()); // Hello
System.out.println(opt2.get()); // NoSuchElementException
- of(T value)
- 새로운 Optional 객체를 생성
- Optional<T> 리턴
// Optional 메소드
Optional<String> opt = Optional.of("Hello");
// 아웃풋
System.out.println(opt.get()); // Hello
- ofNullable(T value)
- 비어 있을 수 있고, 아닐 수도 있는 Optional 객체 생성
// Optional 메소드
String imNull = null;
Optional<String> opt = Optional.ofNullable(imNull);
Optional<String> opt1 = Optional.ofNullable("Hello");
// 아웃풋
System.out.println(opt.isEmpty()); // true
System.out.println(opt1.isEmpty()); // false
- isEmpty()
- Optional 객체가 비어있는지 확인
- 리턴값 boolean
- isPresent()
- Optional 객체가 있는지 확인
- boolean 리턴
- ifPresent(Consumer<? super T> action)
- Optional 객체가 있다면 내부 연산을 실행
- void
- ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
- Optional 객체가 있다면 내부 연산을 실행, 없다면 또 다른 내부 연산을 실행
- void
- or(Supplier <? extends Optional<? extends T>> supplier)
- Optional 객체가 비어있다면 다른 Optional 객체를 반환
- Optional<T> 반환
// 인풋
Optional<String> optional1 = Optional.empty();
Optional<String> optional2 = Optional.of("Hello");
// Optional 메소드 사용
Optional<String> result1 = optional1.or(() -> Optional.of("World"));
Optional<String> result2 = optional2.or(() -> Optional.of("World"));
// 아웃풋
System.out.println(result1.get()); // World
System.out.println(result2.get()); // Hello
- orElse(T other)
- Optional 객체가 비어있다면, 전달된 기본값 other 반환
- T 리턴
- orElseGet(Supplier<? extends T> supplier)
- Optional 객체가 비어있다면, 내부 함수를 실행하여 생성된 기본값을 반환
- 리턴값 T
- 함수가 들어갈 수 있음
- orElseThrow() / orElseThrow(Supplier<? extends X> exceptionSupplier)
- Optional 객체가 비어있다면 Exception 발생
- T 반환
- stream()
- Optional 객체의 값을 stream으로 변환
- Stream<T> 리턴
- toString()
- Optional 내부값을 String 문자여로 바꿔 변환
- String 리턴
- hashcode
- Optional 객체의 HashCode를 반환
- 리턴값 int
// equals 활용
boolean comparePersonById(long id1, long id2) {
Optional<Person> maybePersonA = findById(id1);
Optional<Person> maybePersonB = findById(id2);
return findById(id1).equals(findById(id2));
}
Comparator
- 함수형 인터페이스 형식으로 compare를 받아올 수 있음
@Test
public void testFindMaxValueInIntegerList() throws Exception {
// given
Integer expectedResult = 70;
List<Integer> listOfIntegers = Array.asList(4, 9, 1, 10, 48, 70);
// when
Integer max = listOfIntegers
.stream() // 리스트 객체에서 스트림을 얻어오는 함수
.mapToInt(v -> v) // Integer 스트림을 얻어오는 함수
.max() // max 값을 얻어오는 함수
.orElseThrow(NoSuchElementException::new); // 결과값이 없을 경우 Exception을 전달하는 함수
// then
assertEquals("Max value is 70", expectedResult, max);
}
// 그냥 깡으로 사용
@Test
public void testFindMinValueInCustomObjectList() throws Exception {
// given
Member member1 = new Member("member1", 40);
Member member2 = new Member("member2", 20);
Member member3 = new Member("member3", 30);
List<Member> members = Arrays.asList(member1, member2, member3);
// when
Member minAgeMember = members
.stream() // 리스트 객체에서 스트림을 얻어오는 함수
.min(Comparator.comparing(Member::getAge)) // min 값을 얻어오는 함수
.orElseThrow(NoSuchElementException::new); // 결과값이 없을 경우 Exception을 전달하는 함수
// then
assertEquals("Min age member is member2", member2, minAgeMember);
}
// 객체에서 getAge를 기준으로 min값을 구하는거
.of(T... values) / .of(T t)
- static <T> Stream<T> 반환
- 스트림 생성
.peek(Consumer<? super T> action)
- Stream<T> 반환
- 중간 연산의 결과를 디버깅할 수 있음
fruitList.stream().filter(s -> s.length() > 6)
.peek(e -> System.out.println("글자 수가 6 이상인 과일: " + e))
.filter(s -> s.startsWith("c"))
.peek(e -> System.out.println("c로 시작하는 과일: " + e))
.collect(Collectors.toSet());
/*출력
글자 수가 6 이상인 과일: banana
글자 수가 6 이상인 과일: coconut
c로 시작하는 과일 : cocnut
*/
.reduce(BinaryOperator<T> accumulator) / .reduce(init, accumulator)
- Stream의 요소들을 하나의 데이터로 만드는 작업을 함
- Optional<T> 반환 / T반환
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Optional<Integer> sum = numbers.reduce(Integer::sum);
sum.ifPresent(s -> System.out.println("sum: " + s));
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum = numbers.reduce(10, (total, n) -> total + n);
System.out.println("sum: " + sum);
.skip(long n)
- limit 과 반대로 n개를 무시함
- Stream<T> 반환
.sorted() / .sorted(Comparator<? super T> comparator)
- Stream<T> 반환
// 오름차순
var numbers = List.of(5, 2, 3, 9, 4);
numbers.stream()
.sorted()
.collect(Collectors.toList());
// 내림차순
var numbers = List.of(5, 2, 3, 9, 4);
numbers.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
// Comparator.comparing
var StudentList = List.of(
new Student(4, "tae", 100, 100, 100),
new Student(5, "lob", 75, 75, 100),
new Student(1, "hong", 75, 90, 80),
new Student(2, "sujin", 50, 90, 100),
new Student(3, "kate", 90, 75, 75));
StudentList.stream()
.sorted(Comparator.comparing(Student::getNo))
.collect(Collectors.toList());
// 객체 리스트 정렬 두가지 이상 정렬 기준으로 정렬
var StudentList = List.of(
new Student(4, "tae", 100, 100, 100),
new Student(5, "lob", 75, 75, 100),
new Student(1, "hong", 75, 90, 80),
new Student(2, "sujin", 50, 90, 100),
new Student(3, "kate", 90, 75, 75));
StudentList.stream()
.sorted(Comparator.comparing(Student::getNo)
.thenComparing(Student::getName, Comparator.reverseOrder()))
.collect(Collectors.toList());
.toArray() / .toArray(IntFunction<A[]> generator)
- Object[] / <A> A[] 반환
public static void main(String args[]) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("둘리", 10));
personList.add(new Person("또치", 50));
Stream<Person> personStream1 = personList.stream();
Stream<Person> personStream2 = personList.stream();
// 1. 메서드 참조를 사용하여 생성자 함수 전달
Person[] personArray1 = personStream1.toArray(Person[]::new);
// 2. 람다 표현식을 사용하여 생성자 함수 전달
Person[] personArray2 = personStream2.toArray(size -> new Person[size]);
}
'프로그래밍 > JAVA' 카테고리의 다른 글
[JAVA] Java 12 이후 부터의 switch (0) | 2024.07.29 |
---|---|
[JAVA] 람다식과 메소드참조 정리 (for Stream) (0) | 2024.07.25 |
[Java] UML (0) | 2024.07.21 |
[Java] Optional / Assertion (0) | 2024.04.03 |
[Java] Stream (0) | 2024.03.30 |