Java8 Stream에 대한 자세한 설명과 중간 연산 방법의 예(1)

Java 8에는 컬렉션과 배열을 사용하는 새로운 방법을 제공하는 Stream API가 도입되었습니다. Stream API를 사용하면 데이터, 특히 대규모 데이터를 보다 편리하고 유연하게 처리할 수 있습니다. 여기서는 Java 8의 Stream API에 대해 자세히 소개하겠습니다.

스트림이란?

        스트림은 요소 시퀀스의 표현을 나타내는 Java 8에 도입된 새로운 개념입니다. 구체적으로 말하면 I/O 스트림과 유사하게 컬렉션, 배열 등의 데이터 소스를 추상화한 것이지만 데이터 소스 자체를 변경하지는 않습니다. Stream의 출현으로 우리는 데이터를 보다 편리하고 효율적으로 작업할 수 있게 되었으며 필터링, 매핑, 정렬, 통계 등의 작업을 쉽게 구현할 수 있게 되었으며 동시에 병렬 처리도 지원하여 효율성이 크게 향상되었습니다. 프로그램의.

스트림 작업 유형

Stream API의 작업은 다음 범주로 나눌 수 있습니다.

  1. 스트림 생성 작업: 스트림 생성은 컬렉션이나 기타 데이터 소스를 Stream 개체로 변환하는 프로세스를 나타냅니다. 일반적으로 Stream 클래스의 정적 메서드를 사용하여 Stream.of(), Collections.stream() 등과 같은 스트림 개체를 만들 수 있습니다. 이러한 메서드는 데이터에 대한 다양한 작업을 수행하는 데 사용할 수 있는 Stream 개체를 반환합니다. 다음은 스트림을 생성하는 몇 가지 일반적인 방법입니다.
    of(T... values):创建一个由指定元素组成的流。
    
    empty():创建一个空的流。
    
    generate(Supplier<T> s):创建一个无限流,每次调用 get() 方法都会生成新的数据。
    
    iterate(T seed, UnaryOperator<T> f):创建一个无限流,在每次迭代时都会应用指定的函数。
    
    concat(Stream<? extends T> a, Stream<? extends T> b):创建一个包含两个流的顺序流,先是流 a,再是流 b。
    
    builder():创建一个用于构建链式操作的 Builder 对象。
    
    ofNullable(T t):创建一个包含零个或一个元素的流,元素为指定对象(可以为 null)。
    
    range(int startInclusive, int endExclusive):创建一个包含从 startInclusive 开始(含)到 endExclusive 结束(不含)的整数序列流。
    
    rangeClosed(int startInclusive, int endInclusive):创建一个包含从 startInclusive 开始(含)到 endInclusive 结束(含)的整数序列流。

  2. 중간 작업: 중간 작업은 스트림 유형을 변환하고 스트림을 다른 스트림으로 변환할 수 있는 작업을 의미합니다. 다음은 일반적으로 사용되는 중간 작업 방법 중 일부입니다. 이러한 메서드는 지연 평가되며 데이터 소스에서 데이터를 읽는 대신 새 Stream 개체만 생성합니다.
    filter(Predicate<T> predicate):根据指定的条件过滤流中的元素。
    
    map(Function<T, R> mapper):将流中的元素映射为另外一种类型。
    
    flatMap(Function<T, Stream<R>> mapper):将流中的每个元素都转换成一个新的流,然后把所有的新流合并为一个大流。
    
    distinct():去除流中的重复元素。
    
    sorted():按自然顺序排序流中的元素。
    
    sorted(Comparator<T> comparator):按指定的比较器来排序流中的元素。
    
    peek(Consumer<T> action):对每个元素执行指定的操作,并且返回一个新的流。
    
    limit(long maxSize):从流中截取指定数量的元素。
    
    skip(long n):跳过前面的n个元素,返回剩余的元素。
  3. 터미널 작업: 터미널 작업은 스트림 처리를 종료하고 스트림 실행을 트리거하는 작업을 의미합니다. 다음은 일반적으로 사용되는 종료 작업 방법입니다. 종료 작업은 데이터 소스를 순회하므로 조기에 평가됩니다.
    forEach(Consumer<T> action):对流中的每个元素执行指定的操作。
    
    toArray():将流中的元素转换成数组。
    
    reduce(T identity, BinaryOperator<T> accumulator):使用指定的累加器对流中的元素进行聚合。
    
    collect(Collector<T,A,R> collector):将流中的元素收集到一个容器中。
    
    min(Comparator<T> comparator):返回流中的最小元素。
    
    max(Comparator<T> comparator):返回流中的最大元素。
    
    count():返回流中元素的数量。
    
    anyMatch(Predicate<T> predicate):判断流中是否有任意一个元素匹配指定的条件。
    
    allMatch(Predicate<T> predicate):判断流中是否所有元素都匹配指定的条件。
    
    noneMatch(Predicate<T> predicate):判断流中是否没有任何一个元素匹配指定的条件。
    
    findFirst():返回流中的第一个元素。
    
    findAny():返回流中的任意一个元素。
  4. 기타 방법: Java 8 Stream API는 스트림의 데이터를 더 잘 처리하는 데 도움이 되는 몇 가지 다른 방법도 제공합니다. 그 중 parallel()과 ential()을 사용하면 병렬 처리와 직렬 처리를 선택할 수 있으며, isParallel()은 현재 스트림이 병렬 스트림인지 판단하는 데 도움을 줄 수 있다. 그리고 unordered()는 요소의 순서가 보장될 필요가 없음을 스트림에 알릴 수 있습니다. onClose() 메서드는 스트림이 닫힐 때 지정된 핸들러를 실행합니다. 마지막으로, Spliterator() 메서드를 사용하여 스트림의 요소를 반복하는 데 사용할 수 있는 Spliterator 객체를 만듭니다.

    parallel():将流转为并行流(多线程处理),可以提高处理效率。
    
    sequential():将流转为串行流(单线程处理)。
    
    unordered():告诉流不必保证元素的顺序。
    
    isParallel():判断流是否是并行流。
    
    onClose(Runnable closeHandler):在流关闭时执行指定的处理程序。
    
    spliterator():创建一个 Spliterator 来遍历流的元素。

스트림 중간 작업 방법 상세

filter(술어<? super T> 술어)

 filter(Predicate<? super T> predicate)이 메소드는 스트림의 요소를 필터링하여 지정된 기준을 충족하는 요소만 포함하는 새 스트림을 반환하는 데 사용됩니다.

다음은 사용 예입니다.

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamFilterExample {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        
        List<Integer> filteredList = list.stream()
                                         .filter(n -> n % 2 == 0)
                                         .collect(Collectors.toList());

        System.out.println(filteredList); // 输出 [2, 4]
    }
}

위의 코드는 filter(Predicate<? super T> predicate)메서드를 사용하여 스트림의 요소를 필터링하는 방법을 보여줍니다. 먼저 정수 목록이 생성된 liststream()메서드에 의해 스트림으로 변환됩니다. 그런 다음 filter(n -> n % 2 == 0)메서드를 사용하여 짝수 요소만 포함하는 새 스트림을 가져오고 collect(Collectors.toList())메서드를 사용하여 요소를 목록으로 수집하고 짝수만 포함하는 정수 목록을 가져온 filteredList다음 마지막으로 인쇄합니다.

filter(Predicate<? super T> predicate)이 방법은 Predicate지정된 조건을 충족하는 스트림의 요소를 필터링하는 데 사용되는 기능적 인터페이스인 인터페이스 유형의 매개변수를 사용한다는 점에 유의해야 합니다 . 위 코드에서는 n -> n % 2 == 0짝수 요소를 필터링하는 데 람다 표현식이 사용되었습니다.

map(함수<? super T,? 확장 R> 매퍼) 

map()메소드는 Stream클래스의 중간 작업 메소드로, Function유형의 매개변수를 수신 mapper하고 지정된 규칙에 따라 스트림의 각 요소를 다른 요소에 매핑하고 새 스트림을 생성하는 데 사용됩니다. 특히 이 메서드는 mapper스트림의 각 요소에 함수를 적용하고 함수 반환 값에서 새 스트림을 형성합니다.

예를 들어, 문자열로 구성된 스트림이 있다고 가정합니다. 이제 각 문자열의 길이를 가져와서 새로운 정수 스트림을 생성해야 하며, 다음 방법을 사용하여 다음을 달성할 수 있습니다 map().

List<String> strList = Arrays.asList("Java", "Python", "C#", "JavaScript");
strList.stream()
       .map(str -> str.length())
       .forEach(System.out::println);

위의 코드에서는 먼저 strings 목록에서 하나가 생성된 Stream다음 map()각 문자열이 메서드에 의해 해당 길이로 변환되고 새로운 정수 스트림이 생성됩니다. 마지막으로 메소드를 통해 forEach()각 요소를 콘솔에 출력합니다 .

map()이 메서드는 중간 연산 메서드이므로 스트림에 대한 연산은 즉시 실행되지 않고, 종료 연산 메서드를 만나면 실행된다는 점에 유의해야 한다 . 동시에 map()이 방법은 스트림의 각 요소만 매핑하고 원래 스트림을 변경하지 않으므로 스트림의 후속 요소 처리에는 영향을 미치지 않습니다.

또한 map()메서드의 매핑 함수는 를 반환할 수 없으며 null, 그렇지 않으면 NullPointerException예외가 발생한다는 점에 유의해야 합니다. 매핑 프로세스에서 특정 요소를 제외해야 하는 경우 filter()이 방법을 사용할 수 있습니다.

 flatMap(Function<? super T,?extends Stream<?extends R>> 매퍼)

flatMap()메소드는 하나의 요소를 하나로 매핑한 다음 모든 요소를 ​​하나로 병합하는 Stream클래스의 중간 조작 메소드 입니다 . 특히 이 메서드는 한 요소를 다른 요소로 변환하는 데 사용되는 함수를 인수로 받습니다 . 메소드는 각 요소를 반복하고 변환을 위해 해당 요소를 함수에 전달하여 결국 모든 요소를 ​​새로운 요소로 병합합니다 .StreamStreamStreamflatMap()StreamflatMap()StreamStream

예를 들어, 여러 문자열을 포함하는 목록이 있고 이제 각 문자열을 문자 배열로 변환하고 모든 문자 배열을 문자열 목록으로 결합해야 한다고 가정하면 다음 방법을 사용하여 다음을 달성할 수 있습니다 flatMap().

List<String> strList = Arrays.asList("hello", "world");
List<String> charList = strList.stream()
                               .flatMap(str -> Arrays.stream(str.split("")))
                               .collect(Collectors.toList());
System.out.println(charList); // 输出结果为 ["h", "e", "l", "l", "o", "w", "o", "r", "l", "d"]

위의 코드에서는 먼저 문자열 목록에서 하나를 만든 Stream다음 Arrays.stream(str.split(""))각 문자열에 대해 메서드를 실행하고 문자열을 문자 배열로 변환하고 하나를 반환하고 Stream마지막으로 메서드를 통해 flatMap()모두 Stream새로운 배열로 병합한 Stream다음 collect()다음을 통해 Stream로 변환합니다 . 방법 List.

함수가 배열이나 컬렉션과 같은 개체를 반환하는 경우 메서드는 해당 요소를 결과에 하나씩 추가하는 대신 이 flatMap()개체를 결과에 직접 추가한다는 점에 유의해야 합니다 . 이 객체의 요소를 결과에 하나씩 추가해야 하는 경우 또는 메소드와 함께 메소드를 사용할 수 있습니다 .StreamStreamStreamflatMap()Arrays.stream()Collection.stream()

예를 들어 여러 단어가 포함된 목록이 있고 이제 길이가 3보다 큰 단어의 문자를 소문자로 변환해야 한다고 가정하면 다음 방법을 사용하여 다음을 수행할 수 있습니다 flatMap().

List<String> words = Arrays.asList("Java", "Stream", "API");
List<String> letters = words.stream()
                             .filter(word -> word.length() > 3)
                             .flatMap(word -> Arrays.stream(word.toLowerCase().split("")))
                             .collect(Collectors.toList());
System.out.println(letters); // 输出结果为 ["j", "a", "v", "a", "s", "t", "r", "e", "a", "m"]

위 코드에서는 먼저 단어 목록에서 하나를 만든 Stream다음 길이가 3보다 큰 단어를 필터링하고 Arrays.stream(word.toLowerCase().split(""))각 단어에 대해 메서드를 실행하고 단어를 소문자 알파벳 문자 배열로 변환하고 1을 반환한 다음 Stream마지막으로 flatMap()모두를 Stream다음으로 병합합니다. Stream그런 다음 메소드를 사용하여 collect()변환 Stream합니다 List. toLowerCase()메서드가 문자열 개체를 반환 하므로 split()문자열을 문자 배열로 분할하려면 메서드를 먼저 호출해야 합니다. 

flatMapToDouble(Function<? super T,? 확장 DoubleStream> 매퍼)

flatMapToDouble()메소드는 한 요소를 하나로 매핑 하고 모든 요소를 ​​새로운 요소로 병합하는 Stream클래스의 중간 조작 메소드 입니다 . 특히 이 메서드는 한 요소를 다른 요소로 변환하는 데 사용되는 함수를 인수로 받습니다 . 메소드는 각 요소를 반복하고 변환을 위해 해당 요소를 함수에 전달하여 결국 모든 요소를 ​​새로운 요소로 병합합니다 .DoubleStreamDoubleStreamDoubleStreamflatMapToDouble()DoubleStreamflatMapToDouble()DoubleStreamDoubleStream

예를 들어, 여러 문자열을 포함하는 목록이 있고 이제 각 문자열을 부동 소수점 숫자 배열로 변환하고 모든 부동 소수점 숫자의 합을 계산해야 한다고 가정하면 다음 방법을 사용하여 다음을 수행할 수 있습니다 flatMapToDouble().

List<String> strList = Arrays.asList("1.0", "2.0", "3.0");
double sum = strList.stream()
                    .flatMapToDouble(str -> DoubleStream.of(Double.parseDouble(str)))
                    .sum();
System.out.println(sum); // 输出结果为 6.0

위의 코드에서는 먼저 strings 목록에서 하나를 만든 Stream다음 각 string에서 메서드를 실행하고 DoubleStream.of(Double.parseDouble(str)), 문자열을 부동 소수점 숫자로 변환하고 one을 반환하고 DoubleStream, 마지막 으로 flatMapToDouble()모두 DoubleStream새로운 것으로 병합 DoubleStream하고 sum()해당 메서드를 호출하여 sum을 수행합니다.

함수가 배열이나 컬렉션과 같은 개체를 반환하는 경우 메서드는 해당 요소를 결과에 하나씩 추가하는 대신 이 flatMapToDouble()개체를 결과에 직접 추가한다는 점에 유의해야 합니다 . 이 객체의 요소를 결과에 하나씩 추가해야 하는 경우 또는 메소드와 함께 메소드를 사용할 수 있습니다 .DoubleStreamDoubleStreamDoubleStreamflatMapToDouble()Arrays.stream()Collection.stream()

예를 들어, 여러 단어가 포함된 목록이 있고 이제 길이가 3보다 큰 단어의 문자를 소문자의 ASCII 코드로 변환하고 모든 ASCII 코드의 평균을 계산해야 한다고 가정합니다. 이는 다음 방법을 사용하여 얻을 수 있습니다. flatMapToDouble():

List<String> words = Arrays.asList("Java", "Stream", "API");
double avg = words.stream()
                  .filter(word -> word.length() > 3)
                  .flatMapToDouble(word -> word.toLowerCase().chars().asDoubleStream())
                  .average()
                  .orElse(0.0);
System.out.println(avg); // 输出结果为 99.54545454545455

 위 코드에서는 먼저 단어 목록에서 하나를 만든 Stream다음 길이가 3보다 큰 단어를 필터링하고 word.toLowerCase().chars().asDoubleStream()각 단어에 대해 메서드를 실행하고 단어를 소문자 알파벳 문자 배열로 변환하고 1을 반환한 다음 DoubleStream마지막으로 flatMapToDouble()모두를 DoubleStream다음으로 병합합니다. 새로운 것을 DoubleStream생성하고 average()평균값을 계산하는 메소드를 호출합니다. chars()메서드가 를 반환 하므로 이를 로 변환하려면 메서드를 IntStream호출해야 합니다 . 목록이 비어 있으면 메서드를 호출하여 기본값을 설정할 수 있습니다.asDoubleStream()DoubleStreamorElse()

flatMapToInt(Function<? super T,? 확장 IntStream> 매퍼)

flatMapToInt()메소드는 한 요소를 하나로 매핑 하고 모든 요소를 ​​새로운 요소로 병합하는 Stream클래스의 중간 조작 메소드 입니다 . 특히 이 메서드는 한 요소를 다른 요소로 변환하는 데 사용되는 함수를 인수로 받습니다 . 메소드는 각 요소를 반복하고 변환을 위해 해당 요소를 함수에 전달하여 결국 모든 요소를 ​​새로운 요소로 병합합니다 .IntStreamIntStreamIntStreamflatMapToInt()IntStreamflatMapToInt()IntStreamIntStream

예를 들어, 여러 문자열을 포함하는 목록이 있다고 가정합니다. 이제 각 문자열을 정수 배열로 변환하고 모든 정수의 합을 계산해야 합니다. 이 방법을 사용하면 다음과 같은 결과를 얻을 수 있습니다 flatMapToInt().

List<String> strList = Arrays.asList("1", "2", "3");
int sum = strList.stream()
                 .flatMapToInt(str -> IntStream.of(Integer.parseInt(str)))
                 .sum();
System.out.println(sum); // 输出结果为 6

위 코드에서는 먼저 strings 목록에서 하나를 만든 Stream다음 IntStream.of(Integer.parseInt(str))각 문자열에 대해 메서드를 실행하고, 문자열을 정수로 변환하고 one 을 반환 IntStream하고, 마지막 으로 flatMapToInt()모두 IntStream새로운 문자열로 병합 IntStream하고 sum()메서드를 호출하여 sum을 수행합니다.

함수가 배열이나 컬렉션과 같은 개체를 반환하는 경우 메서드는 해당 요소를 결과에 하나씩 추가하는 대신 이 flatMapToInt()개체를 결과에 직접 추가한다는 점에 유의해야 합니다 . 이 객체의 요소를 결과에 하나씩 추가해야 하는 경우 또는 메소드와 함께 메소드를 사용할 수 있습니다 .IntStreamIntStreamIntStreamflatMapToInt()Arrays.stream()Collection.stream()

예를 들어, 여러 단어가 포함된 목록이 있고 이제 길이가 3보다 큰 단어의 문자를 소문자의 ASCII 코드로 변환하고 모든 ASCII 코드의 평균을 계산해야 한다고 가정합니다. 이는 다음 방법을 사용하여 얻을 수 있습니다. flatMapToInt():

List<String> words = Arrays.asList("Java", "Stream", "API");
double avg = words.stream()
                  .filter(word -> word.length() > 3)
                  .flatMapToInt(word -> word.toLowerCase().chars())
                  .average()
                  .orElse(0.0);
System.out.println(avg); // 输出结果为 99.54545454545455

 위 코드에서는 먼저 단어 목록에서 하나를 만든 Stream다음 길이가 3보다 큰 단어를 필터링하고 word.toLowerCase().chars()각 단어에 대해 메서드를 실행하고 단어를 소문자 알파벳 문자 배열로 변환하고 1을 반환한 다음 IntStream마지막으로 flatMapToInt()모두를 IntStream다음으로 병합합니다. 새로운 것을 IntStream생성하고 average()평균값을 계산하는 메소드를 호출합니다. chars()메서드가 one 을 반환 하므로 IntStream변환하기 위해 다른 메서드를 호출할 필요가 없습니다. 목록이 비어 있으면 orElse()메서드를 호출하여 기본값을 설정할 수 있습니다.

flatMapToLong(Function<? super T,? 확장 LongStream> 매퍼)

flatMapToLong()메소드는 한 요소를 하나로 매핑 하고 모든 요소를 ​​새로운 요소로 병합하는 Stream클래스의 중간 조작 메소드 입니다 . 특히 이 메서드는 한 요소를 다른 요소로 변환하는 데 사용되는 함수를 인수로 받습니다 . 메소드는 각 요소를 반복하고 변환을 위해 해당 요소를 함수에 전달하여 결국 모든 요소를 ​​새로운 요소로 병합합니다 .LongStreamLongStreamLongStreamflatMapToLong()LongStreamflatMapToLong()LongStreamLongStream

예를 들어 여러 문자열을 포함하는 목록이 있다고 가정합니다. 이제 각 문자열을 긴 정수 배열로 변환하고 모든 긴 정수를 합산해야 하며 다음 방법을 사용하여 다음을 수행할 수 있습니다 flatMapToLong().

List<String> strList = Arrays.asList("1", "2", "3");
long sum = strList.stream()
                  .flatMapToLong(str -> LongStream.of(Long.parseLong(str)))
                  .sum();
System.out.println(sum); // 输出结果为 6

위의 코드에서는 먼저 strings 목록에서 하나를 만든 Stream다음 LongStream.of(Long.parseLong(str))각 문자열에 대해 메서드를 실행하고 문자열을 긴 정수로 변환하고 one 을 반환한 다음 LongStream마지막 으로 flatMapToLong()모두 LongStream새로운 문자열로 병합 LongStream하고 sum()해당 메서드를 호출하여 sum을 수행합니다.

함수가 배열이나 컬렉션과 같은 개체를 반환하는 경우 메서드는 해당 요소를 결과에 하나씩 추가하는 대신 이 flatMapToLong()개체를 결과에 직접 추가한다는 점에 유의해야 합니다 . 이 객체의 요소를 결과에 하나씩 추가해야 하는 경우 또는 메소드와 함께 메소드를 사용할 수 있습니다 .LongStreamLongStreamLongStreamflatMapToLong()Arrays.stream()Collection.stream()

예를 들어, 여러 단어가 포함된 목록이 있고 이제 길이가 3보다 큰 단어의 문자를 소문자의 ASCII 코드로 변환하고 모든 ASCII 코드의 평균을 계산해야 한다고 가정합니다. 이는 다음 방법을 사용하여 얻을 수 있습니다. flatMapToLong():

List<String> words = Arrays.asList("Java", "Stream", "API");
double avg = words.stream()
                  .filter(word -> word.length() > 3)
                  .flatMapToLong(word -> word.toLowerCase().chars().asLongStream())
                  .average()
                  .orElse(0.0);
System.out.println(avg); // 输出结果为 99.54545454545455

위 코드에서는 먼저 단어 목록에서 하나를 만든 Stream다음 길이가 3보다 큰 단어를 필터링하고 word.toLowerCase().chars().asLongStream()각 단어에 대해 메서드를 실행하고 단어를 소문자 알파벳 문자 배열로 변환하고 1을 반환한 다음 LongStream마지막으로 flatMapToLong()모두를 LongStream다음으로 병합합니다. 새로운 것을 LongStream생성하고 average()평균값을 계산하는 메소드를 호출합니다. chars()메서드가 를 반환 하므로 이를 로 변환하려면 메서드를 IntStream호출해야 합니다 . 목록이 비어 있으면 메서드를 호출하여 기본값을 설정할 수 있습니다. asLongStream()LongStreamorElse()

 별개의()

distinct()스트림에서 중복 요소를 제거하고 다른 요소로 구성된 새 스트림을 반환하는 데 사용됩니다.

다음은 사용 예입니다.

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DistinctExample {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 3, 2, 4, 2, 1, 5, 6, 4, 3);
        
        List<Integer> distinctList = list.stream()
                                         .distinct()
                                         .collect(Collectors.toList());

        System.out.println(distinctList); // 输出 [1, 3, 2, 4, 5, 6]
    }
}

위의 코드는 distinct()메서드를 사용하여 스트림에서 중복 요소를 제거하는 방법을 보여줍니다. 먼저 정수 목록이 생성된 liststream()메서드에 의해 스트림으로 변환됩니다. 그런 다음 distinct()메소드를 사용하여 다양한 요소로 구성된 새 스트림을 가져오고 collect(Collectors.toList())메소드를 사용하여 요소를 목록으로 수집하고 반복되는 요소가 없는 정수 목록을 얻은 다음 distinctList마지막으로 인쇄합니다.

메소드는 요소가 반복되는지 여부를 결정하기 위해 distinct()객체 hashCode()와 메소드를 사용한다는 점에 유의해야 합니다 . equals()따라서 목록의 요소가 이 두 가지 메서드를 올바르게 구현했는지 확인하세요.

정렬()

sorted() 메서드는 Stream 개체의 요소를 정렬하고 새 Stream 개체를 반환하는 중간 작업입니다. 이 메소드는 기본 정렬을 위해 요소가 속한 클래스의 CompareTo() 메소드를 사용하며 정렬 규칙을 사용자 정의하기 위해 Comparator 함수를 받을 수도 있습니다.

구체적인 사용법은 다음과 같습니다.

  1. 여러 요소를 포함하는 Stream 개체를 만듭니다.
  2. sorted() 메서드를 호출하고 선택적으로 Comparator 함수를 전달합니다.
  3. 이 메서드는 Stream 개체의 요소를 정렬하고 새 Stream 개체를 반환합니다.

예를 들어, 다음 코드는 sorted() 메서드를 사용하여 정수 스트림을 정렬하는 방법을 보여줍니다.

List<Integer> list = Arrays.asList(5, 3, 8, 1, 4);
Stream<Integer> sortedStream = list.stream().sorted();
sortedStream.forEach(System.out::println); // 输出 1 3 4 5 8

위의 코드는 Integer 유형의 목록을 생성하고 이를 Stream 객체로 변환합니다. 다음으로 기본 정렬 규칙을 사용하여 Stream 개체의 요소를 정렬하고 새 Stream 개체를 반환하는 sorted() 메서드를 호출합니다. 마지막으로 forEach() 메서드를 사용하여 새 Stream 객체를 탐색하고 이를 콘솔에 출력합니다.

Stream 객체는 지연 평가되므로 sorted() 메서드 호출 시 정렬 작업이 즉시 수행되지 않고 Stream 객체를 순회할 때 정렬된다는 점에 유의해야 합니다. 정렬 시 Comparator 함수를 사용하는 경우 요소 유형이 Comparable 인터페이스를 구현하는지 확인해야 합니다.

sorted(비교기<? super T> 비교기)

sorted(Comparator<? super T> comparator) 메서드는 Stream 개체의 요소를 정렬하고 새 Stream 개체를 반환하는 중간 작업입니다. 이 방법은 들어오는 Comparator 함수를 사용하여 데이터 정렬을 사용자 지정합니다.

구체적인 사용법은 다음과 같습니다.

  1. 여러 요소를 포함하는 Stream 개체를 만듭니다.
  2. sorted(Comparator<? super T> comparator) 메서드를 호출하고 Comparator 함수를 전달합니다.
  3. 이 메서드는 전달된 Comparator 함수를 사용하여 Stream 개체의 요소를 정렬하고 새 Stream 개체를 반환합니다.

예를 들어, 다음 코드는 sorted() 메서드와 Comparator 함수를 사용하여 문자열 스트림을 정렬하는 방법을 보여줍니다.

List<String> list = Arrays.asList("java", "python", "ruby", "c++");
Stream<String> sortedStream = list.stream().sorted((s1, s2) -> s1.length() - s2.length());
sortedStream.forEach(System.out::println); // 输出 c++ java ruby python

위의 코드는 String 유형 목록을 생성하고 이를 Stream 개체로 변환합니다. 다음으로 sorted() 메서드를 호출하고 문자열을 길이별로 정렬하는 Comparator 함수를 전달합니다. 이 메서드는 지정된 규칙에 따라 요소가 정렬된 새 Stream 개체를 반환합니다. 마지막으로 forEach() 메서드를 사용하여 새 Stream 객체를 탐색하고 이를 콘솔에 출력합니다.

들어오는 Comparator 함수는 임의의 규칙에 따라 정렬될 수 있으며 요소가 속한 클래스의 CompareTo() 메서드에 반드시 의존하지는 않는다는 점에 유의해야 합니다. Stream 객체는 지연 평가되므로 sorted() 메서드 호출 시 즉시 정렬 작업이 수행되지 않고 Stream 객체를 순회할 때 정렬됩니다.

 peek(소비자<? super T> 액션)

peek(Consumer<? super T> action) 메서드는 Stream의 요소 스트림에 일부 작업을 삽입하는 데 사용되는 중간 작업으로, Stream의 요소를 보거나 디버깅하거나 기록할 수 있습니다. 이 방법은 원본 스트림의 요소를 변경하지 않습니다.

구체적인 사용법은 다음과 같습니다.

  1. 여러 요소를 포함하는 Stream 개체를 만듭니다.
  2. peek(Consumer<? super T> action) 메서드를 호출하고 Consumer 개체를 전달하여 스트림의 각 요소를 받습니다.
  3. 이 메서드는 전체 스트림에 대해 지정된 작업을 수행하고 새 Stream 개체를 반환합니다.

예를 들어, 다음 코드는 peek() 메서드를 사용하여 목록의 각 요소 값을 출력하는 방법을 보여줍니다.

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
list.stream().peek(x -> System.out.println("Processing element: " + x))
            .forEach(System.out::println);

출력은 다음과 같습니다

Processing element: 1
1
Processing element: 2
2
Processing element: 3
3
Processing element: 4
4
Processing element: 5
5

위의 코드는 Integer 유형의 목록을 생성하고 이를 Stream 객체로 변환합니다. 다음으로 peek() 메서드를 호출하여 각 요소에 대한 작업을 수행하고 처리 정보를 인쇄하고, 마지막으로 forEach() 메서드를 호출하여 각 요소의 값을 인쇄합니다. peek() 메서드는 원본 Stream의 요소를 변경하지 않으므로 최종 출력은 변환 전 목록과 정확히 동일합니다.

 제한(긴 maxSize)

limit()이 메소드는 긴 매개변수를 수신 하고 최대 지정된 수의 요소를 포함하는 새 스트림으로 원래 스트림을 가로채는 데 사용되는 Stream클래스의 중간 작업 메소드 입니다. maxSize원본 스트림에 포함된 요소 수가 보다 작거나 같으면 maxSize새 스트림은 원본 스트림과 동일합니다. 원본 스트림에 포함된 요소 수가 보다 크면 maxSize새 스트림에는 이전 maxSize요소 만 포함됩니다. .

예를 들어, 숫자로 구성된 스트림이 있고 이제 그 안에 있는 처음 5개 요소를 가져와야 한다고 가정하면 다음 limit()방법을 사용하여 다음을 달성할 수 있습니다.

List<Integer> numList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
numList.stream()
       .limit(5)
       .forEach(System.out::println);

위 코드에서는 먼저 숫자 목록에서 하나를 만든 Stream다음 limit()메서드를 통해 스트림을 최대 5개의 요소를 포함하는 새 스트림으로 가로채고 forEach()각 요소는 메서드를 통해 콘솔에 출력됩니다. 메소드가 호출되었으므로 limit()출력에는 처음 5개 요소만 포함됩니다.

limit()이 메서드는 중간 연산 메서드이므로 스트림에 대한 연산은 즉시 실행되지 않고, 종료 연산 메서드를 만나면 실행된다는 점에 유의해야 한다 . 동시에 limit()이 메서드는 스트림 요소의 일부만 가로채기 때문에 스트림의 후속 요소 처리에는 영향을 미치지 않습니다.

또한 제공된 매개변수 값이 0보다 작거나 같으면 새 스트림에 요소가 포함되지 않습니다. 제공된 인수 값이 원래 스트림의 요소 수보다 크면 새 스트림은 원래 스트림과 동일합니다.

건너뛰기(긴 n)

Skip(long n) 메서드는 처음 n개 요소를 건너뛰고 새 Stream 개체를 반환하는 중간 작업입니다. n이 스트림의 요소 수보다 크면 빈 Stream 객체가 반환됩니다.

구체적인 사용법은 다음과 같습니다.

  1. 여러 요소를 포함하는 Stream 개체를 만듭니다.
  2. Skip(long n) 메서드를 호출하고 건너뛸 요소 수 n을 전달합니다.
  3. 이 메소드는 원래 스트림의 나머지 요소를 포함하는 새 Stream 객체를 반환합니다.

예를 들어, 다음 코드는 Skip() 메서드를 사용하여 문자열 스트림의 처음 두 요소를 건너뛰는 방법을 보여줍니다.

List<String> list = Arrays.asList("apple", "banana", "orange", "pear");
Stream<String> stream = list.stream().skip(2);
stream.forEach(System.out::println); // 输出 orange pear

위의 코드는 String 유형 목록을 생성하고 이를 Stream 개체로 변환합니다. 그런 다음 처음 두 요소를 건너뛰도록 지정하여 Skip() 메서드를 호출합니다. 이 메소드는 원래 스트림의 나머지 요소를 포함하는 새 Stream 객체를 반환합니다. 마지막으로 forEach() 메서드를 사용하여 새 Stream 객체를 탐색하고 이를 콘솔에 출력합니다.

Stream 객체는 지연 평가되므로 Skip() 메서드 호출 시 건너뛰기 작업이 즉시 수행되지 않고 Stream 객체를 순회할 때 건너뜁니다. 건너뛴 요소도 메모리에 보관되지 않으므로 대규모 데이터 세트로 작업할 때 메모리 소비가 줄어듭니다.

추천

출처blog.csdn.net/Ascend1977/article/details/131094398