>  기사  >  Java  >  Java8의 Stream 세부 사용법 요약

Java8의 Stream 세부 사용법 요약

WBOY
WBOY앞으로
2022-10-05 09:00:272296검색

이 기사에서는 Stream의 세부 사용법에 대한 관련 문제를 주로 소개하는 Java에 대한 관련 지식을 제공합니다. 버전의 새로운 Stream은 동일한 버전에 나타나는 Lambda와 함께 컬렉션을 운영하는 훌륭한 방법을 제공합니다( 컬렉션) 매우 편리합니다. 아래에서 살펴보겠습니다. 모든 사람에게 도움이 되기를 바랍니다.

Java8의 Stream 세부 사용법 요약

추천 학습: "java 비디오 튜토리얼"

1. 개요

Java 8은 동일한 버전에 나타나는 Lambda와 결합된 매우 성공적인 버전입니다. 일련의 작업(컬렉션)은 매우 편리합니다. Stream은 선언적 방식으로 데이터 컬렉션을 처리할 수 있는 JDK8의 새로운 멤버입니다. Stream 스트림은 데이터 컬렉션을 탐색하기 위한 고급 반복자로 간주될 수 있습니다. 스트림은 Java 8에서 컬렉션을 처리하기 위한 핵심 추상 개념입니다. 스트림은 컬렉션에 대해 수행하려는 작업을 지정할 수 있으며 데이터 찾기/필터링/필터링, 정렬, 집계 및 매핑과 같은 매우 복잡한 작업을 수행할 수 있습니다. Stream API를 사용하여 컬렉션 데이터에 대해 작업하는 것은 SQL을 사용하여 데이터베이스 쿼리를 수행하는 것과 유사합니다. Stream API를 사용하여 작업을 병렬로 수행할 수도 있습니다. 즉, Stream API는 데이터를 처리하는 효율적이고 사용하기 쉬운 방법을 제공합니다.

1. 스트림 사용의 이점

코드는 작업을 수행하는 방법보다는 수행하려는 내용을 설명하는 선언적 방식으로 작성됩니다.
여러 기본 작업을 연결하여 코드를 명확하고 읽기 쉽게 유지하면서 복잡한 데이터 처리 파이프라인을 표현할 수 있습니다.

2. 스트림이란 무엇입니까?

데이터 처리 작업을 지원하는 소스에서 일련의 요소를 생성합니다. 데이터 소스는 컬렉션, 배열 또는 IO 리소스일 수 있습니다.

운영 관점에서 스트림은 컬렉션과 다릅니다. 스트림의 목적은 데이터를 처리하는 것이며 알고리즘과 계산에 관한 것입니다.

컬렉션을 스트림의 데이터 소스로 사용하는 경우 스트림을 생성해도 데이터가 흐르지 않습니다. 스트림 종료 작업에 값이 필요한 경우 스트림은 스트림에서만 값을 가져옵니다. 한 번 사용되었습니다.

스트림의 핵심 아이디어는 계산을 지연시키는 것이며 스트림은 필요할 때까지 값을 계산하지 않습니다.
Java8의 Stream 세부 사용법 요약
스트림은 배열이나 컬렉션에서 생성될 수 있습니다. 스트림에 대한 작업은 두 가지 유형으로 나뉩니다.

중간 작업, 새 스트림이 반환될 때마다 여러 개가 있을 수 있습니다.

터미널 작업, 각 스트림은 하나의 터미널 작업만 수행할 수 있으며, 터미널 작업이 완료된 후에는 스트림을 다시 사용할 수 없습니다. 터미널 작업은 새로운 컬렉션이나 가치를 생성합니다.

특징:

은 데이터 구조가 아니며 데이터를 저장하지 않습니다.

원본 데이터 소스를 수정하지 않고, 조작된 데이터를 다른 개체에 저장합니다. (예약: 결국 peek 메소드는 스트림의 요소를 수정할 수 있습니다.)

지연 평가. 스트림의 중간 처리 중에는 작업이 기록만 되고 종료 작업이 즉시 실행되지 않습니다. 실제 연산이 수행되기 전에 수행됩니다.

2. Classification

Java8의 Stream 세부 사용법 요약

Stateless: 요소 처리가 이전 요소의 영향을 받지 않음을 의미합니다.

Stateful: 모든 요소를 ​​가져온 후에만 작업을 계속할 수 있음을 의미합니다.

비단락 작동: 최종 결과를 얻으려면 모든 요소를 ​​처리해야 함을 의미합니다.

단락 작동: A와 같은 조건을 충족하는 특정 요소를 만날 때 최종 결과를 얻을 수 있음을 의미합니다. || B. A가 참인 한 판단은 필요하지 않습니다. B의 결과입니다.

3. 스트림 생성

스트림은 컬렉션 배열을 통해 생성할 수 있습니다.

1. java.util.Collection.stream() 메서드를 사용하여 컬렉션이 포함된 스트림을 생성합니다.

List<string> list = Arrays.asList("a", "b", "c");// 创建一个顺序流
Stream<string> stream = list.stream();// 创建一个并行流
Stream<string> parallelStream = list.parallelStream();</string></string></string>

2. java.util.Arrays.stream(T[]array) 메서드를 사용하여 컬렉션이 포함된 스트림을 생성합니다. array

int[] array={1,3,5,6,8};IntStream stream = Arrays.stream(array);

3. 스트림 정적 메소드 사용: of(), iterate(), generate()

Stream<integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
 Stream<integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);stream2.forEach(System.out::println);
 Stream<double> stream3 = Stream.generate(Math::random).limit(3);stream3.forEach(System.out::println);</double></integer></integer>

출력 결과:

0 3 6 90.67961569092719940.19143142088542830.8116932592396652

스트림과 병렬 스트림의 간단한 차이점: 스트림은 순차적 스트림이며 메인 스레드입니다. 스트림에 대한 작업을 순차적으로 수행하는 반면, ParallelStream은 병렬 스트림이고 내부적으로 멀티스레드 병렬 실행 방식으로 스트림을 작동하지만, 스트림의 데이터 처리에는 순서 요구 사항이 없다는 것이 전제입니다. 예를 들어 컬렉션에서 홀수를 필터링하면 둘 사이의 처리 차이는 다음과 같습니다.
Java8의 Stream 세부 사용법 요약
스트림의 데이터 양이 충분히 크면 병렬 스트림이 처리 속도를 높일 수 있습니다.

병렬 스트림을 직접 생성하는 것 외에도 병렬()을 통해 순차 스트림을 병렬 스트림으로 변환할 수도 있습니다.

Optional<integer> findFirst = list.stream().parallel().filter(x->x>6).findFirst();</integer>

IV. 스트림 API 소개

在这里插入Java8의 Stream 세부 사용법 요약描述
Java8의 Stream 세부 사용법 요약

先贴上几个案例,水平高超的同学可以挑战一下:从员工集合中筛选出salary大于8000的员工,并放置到新的集合里。统计员工的最高薪资、平均薪资、薪资之和。将员工按薪资从高到低排序,同样薪资者年龄小者在前。将员工按性别分类,将员工按性别和地区分类,将员工按薪资是否高于8000分为两部分。用传统的迭代处理也不是很难,但代码就显得冗余了,跟Stream相比高下立判。

전제 조건: 직원 클래스

static List<person> personList = new ArrayList<person>();private static void initPerson() {
    personList.add(new Person("张三", 8, 3000));
    personList.add(new Person("李四", 18, 5000));
    personList.add(new Person("王五", 28, 7000));
    personList.add(new Person("孙六", 38, 9000));}</person></person>

1 . 순회/ 일치(foreach/find/match)

Stream은 Stream의 요소가 Optional 유형으로 존재한다는 점을 제외하면 컬렉션과 유사한 순회 및 일치 요소도 지원합니다. 스트림 순회 및 일치는 매우 간단합니다.

// import已省略,请自行添加,后面代码亦是
 
public class StreamTest {
  public static void main(String[] args) {
        List<integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
 
        // 遍历输出符合条件的元素
        list.stream().filter(x -> x > 6).forEach(System.out::println);
        // 匹配第一个
        Optional<integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
        // 匹配任意(适用于并行流)
        Optional<integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
        // 是否包含符合特定条件的元素
        boolean anyMatch = list.stream().anyMatch(x -> x <h3>2、按条件匹配filter</h3>
<p><img src="https://img.php.cn/upload/article/000/000/067/c32799257ddfee7ae65dfaf7bce4b27c-5.png" alt="在这里插入Java8의 Stream 세부 사용법 요약描述"></p>
<p><strong>(1)筛选员工中已满18周岁的人,并形成新的集合</strong></p>
<pre class="brush:php;toolbar:false">/**
 * 筛选员工中已满18周岁的人,并形成新的集合
 * @思路
 * List<person> list = new ArrayList<person>();
 * for(Person person : personList) {
 *     if(person.getAge() >= 18) {
 *          list.add(person);
 *     }
 * }
 */
private static void filter01() {
    initPerson();
    List<person> collect = personList.stream().filter(x -> x.getAge()>=18).collect(Collectors.toList());
    System.out.println(collect);}</person></person></person>

在这里插入Java8의 Stream 세부 사용법 요약描述
(2)自定义条件匹配
Java8의 Stream 세부 사용법 요약

3、聚合max、min、count

Java8의 Stream 세부 사용법 요약

(1)获取String集合中最长的元素

/**
 * 获取String集合中最长的元素
 * @思路
 * List<string> list = Arrays.asList("zhangsan", "lisi", "wangwu", "sunliu");
 * String max = "";
 * int length = 0;
 * int tempLength = 0;
 * for(String str : list) {
 *     tempLength = str.length();
 *     if(tempLength > length) {
 *         length  = str.length();
 *         max = str;
 *      }
 * }
 * @return zhangsan
 */
private static void test02() {
    List<string> list = Arrays.asList("zhangsan", "lisi", "wangwu", "sunliu");
    Comparator super String> comparator = Comparator.comparing(String::length);
    Optional<string> max = list.stream().max(comparator);
    System.out.println(max);}</string></string></string>

Java8의 Stream 세부 사용법 요약
(2)获取Integer集合中的最大值

//获取Integer集合中的最大值
private static void test05() {
    List<integer> list = Arrays.asList(1, 17, 27, 7);
    Optional<integer> max = list.stream().max(Integer::compareTo);
    // 自定义排序
    Optional<integer> max2 = list.stream().max(new Comparator<integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o1.compareTo(o2);
        }
    });
    System.out.println(max2);}</integer></integer></integer></integer>

Java8의 Stream 세부 사용법 요약

//获取员工中年龄最大的人
private static void test06() {
    initPerson();
    Comparator super Person> comparator = Comparator.comparingInt(Person::getAge);
    Optional<person> max = personList.stream().max(comparator);
    System.out.println(max);}</person>

(3)获取员工中年龄最大的人
在这里插入Java8의 Stream 세부 사용법 요약描述
4)计算integer集合中大于10的元素的个数
在这里插入Java8의 Stream 세부 사용법 요약描述

4、map与flatMap

map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

Java8의 Stream 세부 사용법 요약

(1)字符串大写
Java8의 Stream 세부 사용법 요약
(2)整数数组每个元素+3

/**
 * 整数数组每个元素+3
 * @思路
 * List<integer> list = Arrays.asList(1, 17, 27, 7);
   List<integer> list2 = new ArrayList<integer>();
   for(Integer num : list) {
      list2.add(num + 3);
   }
   @return [4, 20, 30, 10]
 */
private static void test09() {
    List<integer> list = Arrays.asList(1, 17, 27, 7);
    List<integer> collect = list.stream().map(x -> x + 3).collect(Collectors.toList());
    System.out.println(collect);}</integer></integer></integer></integer></integer>

(3)公司效益好,每人涨2000

/**
 * 公司效益好,每人涨2000
 *
 */
private static void test10() {
    initPerson();
    List<person> collect = personList.stream().map(x -> {
        x.setAge(x.getSalary()+2000);
        return x;
    }).collect(Collectors.toList());
    System.out.println(collect);}</person>

(4)将两个字符数组合并成一个新的字符数组

/**
 * 将两个字符数组合并成一个新的字符数组
 *
 */
private static void test11() {
    String[] arr = {"z, h, a, n, g", "s, a, n"};
    List<string> list = Arrays.asList(arr);
    System.out.println(list);
    List<string> collect = list.stream().flatMap(x -> {
        String[] array = x.split(",");
        Stream<string> stream = Arrays.stream(array);
        return stream;
    }).collect(Collectors.toList());
    System.out.println(collect);}</string></string></string>

(5)将两个字符数组合并成一个新的字符数组

/**
 * 将两个字符数组合并成一个新的字符数组
 * @return [z,  h,  a,  n,  g, s,  a,  n]
 */
private static void test11() {
    String[] arr = {"z, h, a, n, g", "s, a, n"};
    List<string> list = Arrays.asList(arr);
    List<string> collect = list.stream().flatMap(x -> {
        String[] array = x.split(",");
        Stream<string> stream = Arrays.stream(array);
        return stream;
    }).collect(Collectors.toList());
    System.out.println(collect);}</string></string></string>

5、规约reduce

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。
Java8의 Stream 세부 사용법 요약
(1)求Integer集合的元素之和、乘积和最大值

/**
 * 求Integer集合的元素之和、乘积和最大值
 *
 */
private static void test13() {
    List<integer> list = Arrays.asList(1, 2, 3, 4);
    //求和
    Optional<integer> reduce = list.stream().reduce((x,y) -> x+ y);
    System.out.println("求和:"+reduce);
    //求积
    Optional<integer> reduce2 = list.stream().reduce((x,y) -> x * y);
    System.out.println("求积:"+reduce2);
    //求最大值
    Optional<integer> reduce3 = list.stream().reduce((x,y) -> x>y?x:y);
    System.out.println("求最大值:"+reduce3);}</integer></integer></integer></integer>

(2)求所有员工的工资之和和最高工资

/*
 * 求所有员工的工资之和和最高工资
 */
private static void test14() {
    initPerson();
    Optional<integer> reduce = personList.stream().map(Person :: getSalary).reduce(Integer::sum);
    Optional<integer> reduce2 = personList.stream().map(Person :: getSalary).reduce(Integer::max);
    System.out.println("工资之和:"+reduce);
    System.out.println("最高工资:"+reduce2);}</integer></integer>

6、收集(toList、toSet、toMap)

取出大于18岁的员工转为map

/**
 * 取出大于18岁的员工转为map
 *
 */
private static void test15() {
    initPerson();
    Map<string> collect = personList.stream().filter(x -> x.getAge() > 18).collect(Collectors.toMap(Person::getName, y -> y));
    System.out.println(collect);}</string>

7、collect

Collectors提供了一系列用于数据统计的静态方法:

计数: count

平均值: averagingInt、 averagingLong、 averagingDouble

最值: maxBy、 minBy

求和: summingInt、 summingLong、 summingDouble

统计以上所有: summarizingInt、 summarizingLong、 summarizingDouble

/**
 * 统计员工人数、平均工资、工资总额、最高工资
 */
private static void test01(){
    //统计员工人数
    Long count = personList.stream().collect(Collectors.counting());
    //求平均工资
    Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
    //求最高工资
    Optional<integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
    //求工资之和
    Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));
    //一次性统计所有信息
    DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
    System.out.println("统计员工人数:"+count);
    System.out.println("求平均工资:"+average);
    System.out.println("求最高工资:"+max);
    System.out.println("求工资之和:"+sum);
    System.out.println("一次性统计所有信息:"+collect);}</integer>

8、分组(partitioningBy/groupingBy)

分区:将stream按条件分为两个 Map,比如员工按薪资是否高于8000分为两部分。

分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
Java8의 Stream 세부 사용법 요약

将员工按薪资是否高于8000分为两部分;将员工按性别和地区分组

public class StreamTest {
  public static void main(String[] args) {
    personList.add(new Person("zhangsan",25, 3000, "male", "tieling"));
        personList.add(new Person("lisi",27, 5000, "male", "tieling"));
        personList.add(new Person("wangwu",29, 7000, "female", "tieling"));
        personList.add(new Person("sunliu",26, 3000, "female", "dalian"));
        personList.add(new Person("yinqi",27, 5000, "male", "dalian"));
        personList.add(new Person("guba",21, 7000, "female", "dalian"));
 
    // 将员工按薪资是否高于8000分组
        Map<boolean>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
        // 将员工按性别分组
        Map<string>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));
        // 将员工先按性别分组,再按地区分组
        Map<string>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
        System.out.println("员工按薪资是否大于8000分组情况:" + part);
        System.out.println("员工按性别分组情况:" + group);
        System.out.println("员工按性别、地区:" + group2);
  }}</string></string></boolean>

9、连接joining

joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。
Java8의 Stream 세부 사용법 요약

10、排序sorted

将员工按工资由高到低(工资一样则按年龄由大到小)排序

private static void test04(){
    // 按工资升序排序(自然排序)
    List<string> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
            .collect(Collectors.toList());
    // 按工资倒序排序
    List<string> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
            .map(Person::getName).collect(Collectors.toList());
    // 先按工资再按年龄升序排序
    List<string> newList3 = personList.stream()
            .sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)
            .collect(Collectors.toList());
    // 先按工资再按年龄自定义排序(降序)
    List<string> newList4 = personList.stream().sorted((p1, p2) -> {
        if (p1.getSalary() == p2.getSalary()) {
            return p2.getAge() - p1.getAge();
        } else {
            return p2.getSalary() - p1.getSalary();
        }
    }).map(Person::getName).collect(Collectors.toList());
 
    System.out.println("按工资升序排序:" + newList);
    System.out.println("按工资降序排序:" + newList2);
    System.out.println("先按工资再按年龄升序排序:" + newList3);
    System.out.println("先按工资再按年龄自定义降序排序:" + newList4);}</string></string></string></string>

11、提取/组合

流也可以进行合并、去重、限制、跳过等操作。

private static void test05(){
    String[] arr1 = { "a", "b", "c", "d" };
    String[] arr2 = { "d", "e", "f", "g" };
    Stream<string> stream1 = Stream.of(arr1);
    Stream<string> stream2 = Stream.of(arr2);
    // concat:合并两个流 distinct:去重
    List<string> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
    // limit:限制从流中获得前n个数据
    List<integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
    // skip:跳过前n个数据
    List<integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
 
    System.out.println("流合并:" + newList);
    System.out.println("limit:" + collect);
    System.out.println("skip:" + collect2);}</integer></integer></string></string></string>

12、读取文件的流操作

Java8의 Stream 세부 사용법 요약

13、计算两个list中的差集

//计算两个list中的差集
List<string> reduce1 = allList.stream().filter(item -> !wList.contains(item)).collect(Collectors.toList());</string>

推荐学习:《java视频教程

위 내용은 Java8의 Stream 세부 사용법 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제