首页 > 编程语言 >Java Stream中的API你都用过了吗?

Java Stream中的API你都用过了吗?

时间:2023-11-22 12:56:38浏览次数:35  
标签:java Stream age util add API Java public

公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享。

在本教程中,您将通过大量示例来学习 Java 8 Stream API。

Java 在 Java 8 中提供了一个新的附加包,称为 java.util.stream。该包由类、接口和枚举组成,允许对元素进行函数式操作。 您可以通过在程序中导入 java.util.stream包来使用流。

Stream提供以下功能:

Stream不存储元素。它只是通过计算操作的管道传送来自数据结构、数组或 I/O 通道等源的元素。

Stream本质上是函数式的,对流执行的操作不会修改其源。例如,过滤从集合获取的 Stream 会生成一个没有过滤元素的新 Stream,而不是从源集合中删除元素。

Stream是惰性的,仅在需要时才计算代码,在流的生命周期中,流的元素仅被访问一次。

与迭代器一样,必须生成新流才能重新访问源中的相同元素。
您可以使用 Stream 来 过滤、收集、打印以及 从一种数据结构转换为其他数据结构等。

Stream API 示例

1. 创建一个空的Stream

在创建空流时,应使用 empty() 方法:

Stream<String> stream = Stream.empty();
stream.forEach(System.out::println);

通常情况下,在创建时会使用 empty() 方法,以避免在没有元素的流中返回 null:

public Stream<String> streamOf(List<String> list) {
    return list == null || list.isEmpty() ? Stream.empty() : list.stream();
}

2.从集合中创建流

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;

public class StreamCreationExamples {
    public static void main(String[] args) throws IOException {

        Collection<String> collection = Arrays.asList("JAVA", "J2EE", "Spring", "Hibernate");
        Stream<String> stream2 = collection.stream();
        stream2.forEach(System.out::println);

        List<String> list = Arrays.asList("JAVA", "J2EE", "Spring", "Hibernate");
        Stream<String> stream3 = list.stream();
        stream3.forEach(System.out::println);

        Set<String> set = new HashSet<>(list);
        Stream<String> stream4 = set.stream();
        stream4.forEach(System.out::println);
    }
}

输出

JAVA
J2EE
Spring
Hibernate
JAVA
J2EE
Spring
Hibernate
JAVA
Hibernate
J2EE
Spring

3. 从数组中创建流对象

数组可以是流的源,也可以从现有数组或数组的一部分创建数组:

import java.util.Arrays;
import java.util.stream.Stream;

public class StreamCreationExample {
    public static void main(String[] args) {
        // 使用Arrays.stream()创建流
        int[] numbers = {1, 2, 3, 4, 5};
        Stream<Integer> stream1 = Arrays.stream(numbers);
        System.out.println("Using Arrays.stream():");
        stream1.forEach(System.out::println);

        // 使用Stream.of()创建流
        String[] names = {"Alice", "Bob", "Charlie"};
        Stream<String> stream2 = Stream.of(names);
        System.out.println("Using Stream.of():");
        stream2.forEach(System.out::println);

        // 使用Stream.builder()创建流
        String[] colors = {"Red", "Green", "Blue"};
        Stream.Builder<String> builder = Stream.builder();
        for (String color : colors) {
            builder.add(color);
        }
        Stream<String> stream3 = builder.build();
        System.out.println("Using Stream.builder():");
        stream3.forEach(System.out::println);
    }
}

输出

Using Arrays.stream():
1
2
3
4
5
Using Stream.of():
Alice
Bob
Charlie
Using Stream.builder():
Red
Green
Blue

4. 使用Stream过滤一个集合示例

在下面的示例中,我们不使用流过滤数据,看看代码是什么样的,同时我们在给出一个使用stream过滤的示例,对比一下

不使用Stream过滤一个集合示例

import java.util.ArrayList;
import java.util.List;

public class FilterWithoutStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(10);
        numbers.add(20);
        numbers.add(30);
        numbers.add(40);
        numbers.add(50);

        List<Integer> filteredNumbers = new ArrayList<>();
        for (Integer number : numbers) {
            if (number > 30) {
                filteredNumbers.add(number);
            }
        }

        System.out.println("Filtered numbers (without Stream):");
        for (Integer number : filteredNumbers) {
            System.out.println(number);
        }
    }
}

输出:

Filtered numbers (without Stream):
40
50

使用 Stream 过滤集合示例:

import java.util.ArrayList;
import java.util.List;

public class FilterWithStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(10);
        numbers.add(20);
        numbers.add(30);
        numbers.add(40);
        numbers.add(50);

        List<Integer> filteredNumbers = numbers.stream()
                .filter(number -> number > 30)
                .toList();

        System.out.println("Filtered numbers (with Stream):");
        filteredNumbers.forEach(System.out::println);
    }
}

输出:

Filtered numbers (with Stream):
40
50

前后我们对比一下,可以看到,使用 Stream 进行集合过滤可以更加简洁和直观,减少了手动迭代和添加元素的步骤。它提供了一种声明式的编程风格,使代码更易读、可维护和可扩展。

5. 使用Stream过滤和遍历集合

在下面的示例中,我们使用 filter() 方法进行过滤,使用 forEach() 方法对数据流进行迭代:

import java.util.ArrayList;
import java.util.List;

public class FilterAndIterateWithStreamExample {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        names.add("David");
        names.add("Eve");

        System.out.println("Filtered names starting with 'A':");
        names.stream()
                .filter(name -> name.startsWith("A"))
                .forEach(System.out::println);
    }
}

输出

Filtered names starting with 'A':
Alice

在上述示例中,我们有一个字符串列表 names,其中包含了一些名字。
我们使用 Stream 进行过滤和迭代操作以查找以字母 "A" 开头的名字。

6.使用Collectors方法求和

我们还可以使用Collectors计算数值之和。

在下面的示例中,我们使用Collectors类及其指定方法计算所有产品价格的总和。

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

public class SumByUsingCollectorsMethods {
    public static void main(String[] args) {
        List < Product > productsList = new ArrayList < Product > ();
        productsList.add(new Product(1, "HP Laptop", 25000f));
        productsList.add(new Product(2, "Dell Laptop", 30000f));
        productsList.add(new Product(3, "Lenevo Laptop", 28000f));
        productsList.add(new Product(4, "Sony Laptop", 28000f));
        productsList.add(new Product(5, "Apple Laptop", 90000f));
        
        double totalPrice3 = productsList.stream()
            .collect(Collectors.summingDouble(product -> product.getPrice()));
        System.out.println(totalPrice3);

    }
}

输出

201000.0

7. 使用Stream查找年龄最大和最小的学生

假设有一个 Student 类具有 name 和 age 属性。我们可以使用 Stream 来查找学生集合中年龄的最大和最小值,并打印出相应的学生信息。以下是一个示例:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

public class StudentStreamExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Alice", 20));
        students.add(new Student("Bob", 22));
        students.add(new Student("Charlie", 19));
        students.add(new Student("David", 21));

        // 查找年龄最大的学生
        Optional<Student> maxAgeStudent = students.stream()
                .max(Comparator.comparingInt(Student::getAge));

        // 查找年龄最小的学生
        Optional<Student> minAgeStudent = students.stream()
                .min(Comparator.comparingInt(Student::getAge));

        // 打印最大和最小年龄的学生信息
        System.out.println("Student with maximum age:");
        maxAgeStudent.ifPresent(System.out::println);

        System.out.println("Student with minimum age:");
        minAgeStudent.ifPresent(System.out::println);
    }
}

class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

输出:

Student with maximum age:
Student{name='Bob', age=22}
Student with minimum age:
Student{name='Charlie', age=19}

8. 使用Stream转换List为Map

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class StudentStreamToMapExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Alice", 20));
        students.add(new Student("Bob", 22));
        students.add(new Student("Charlie", 19));
        students.add(new Student("David", 21));

        // 将学生列表转换为 Map,以姓名为键,学生对象为值
        Map<String, Student> studentMap = students.stream()
                .collect(Collectors.toMap(Student::getName, student -> student));

        // 打印学生 Map
        for (Map.Entry<String, Student> entry : studentMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

输出

David: Student{name='David', age=21}
Bob: Student{name='Bob', age=22}
Charlie: Student{name='Charlie', age=19}
Alice: Student{name='Alice', age=20}

在上面示例中,我们使用Collectors.toMap() 方法将学生列表转换为 Map。我们指定了键提取器 Student::getName,将学生的姓名作为键。对于值提取器,我们使用了一个匿名函数 student -> student,它返回学生对象本身作为值。

9. 使用Stream把List对象转换为另一个List对象

假设我们有一个 Person 类,其中包含姓名和年龄属性。我们可以使用 Stream 来将一个 List 对象转换为另一个 List 对象,其中只包含人员的姓名。以下是一个示例:

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

public class ListTransformationExample {
    public static void main(String[] args) {
        List<Person> persons = new ArrayList<>();
        persons.add(new Person("Alice", 20));
        persons.add(new Person("Bob", 22));
        persons.add(new Person("Charlie", 19));

        // 将 Person 列表转换为只包含姓名的 String 列表
        List<String> names = persons.stream()
                .map(Person::getName)
                .collect(Collectors.toList());

        // 打印转换后的姓名列表
        System.out.println(names);
    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

输出:

  [Alice, Bob, Charlie]

在上述示例中,我们有一个 Person 类,其中包含姓名和年龄属性。我们创建了一个 persons 列表,并添加了几个 Person 对象。

使用Stream,我们通过调用 map() 方法并传入一个方法引用 Person::getName,最后,我们使用 collect() 方法和 Collectors.toList() 将转换后的姓名收集到一个新的列表中。

API

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

标签:java,Stream,age,util,add,API,Java,public
From: https://www.cnblogs.com/waldron/p/17848756.html

相关文章

  • C/C++ 使用API实现数据压缩与解压缩
    在Windows编程中,经常会遇到需要对数据进行压缩和解压缩的情况,数据压缩是一种常见的优化手段,能够减小数据的存储空间并提高传输效率。Windows提供了这些API函数,本文将深入探讨使用WindowsAPI进行数据压缩与解压缩的过程,主要使用ntdll.dll库中的相关函数。关键函数介绍RtlGetComp......
  • WIZnet socket API 前言
    WIZnetsocketAPIWIZnetsocketAPIs基于BerkeleysocketAPIs,因此有着相似的名字和接口。但是也是有着些许的不同。APIWIZnetBerkeleysocket()OObind()XOlisten()OOconnect()OOaccept()XOrecv()OOsend()OOrecvfrom()OO......
  • java类转mysql表创建语句
    packagecn.eangaie.cloud.wx3562;importcn.hutool.core.io.FileUtil;importcn.hutool.core.lang.Console;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importio.swagger.annotations.ApiModelProper......
  • Java报表开发工具总结
    Java报表工具,首先可以分成两大类:纯Java报表工具,和支持Java的报表工具。支持Java的报表工具支持Java的报表工具.其实就是非Java的报表工具,但是可以在Java程序中调用,这样的产品很多,总的讲一大类是采用独立报表服务器的,如Bo/CrystalReport,Brio,Cognos等等;另一大类是在前端有控件的,......
  • 大数据开发要学什么java还是python?
    在大数据开发领域,Java和Python都是备受青睐的编程语言。它们分别具有各自独特的特点和优势,在大数据处理方面也有不同的应用场景。以下是对Java和Python在大数据开发中的应用、优势以及学习建议的详细描述。Java在大数据开发中的应用和优势1.应用场景Hadoop生态圈:Java广泛......
  • 【Java】乡镇卫生院、社区卫生服务中心云HIS源码
    云HIS采用云端SaaS服务的方式提供,用户通过浏览器即能访问,无需关注系统的部署、维护、升级等问题,系统充分考虑了模板化、配置化、智能化、扩展化等设计方法,覆盖了基层医院机构的主要工作流程,能够与监管系统有序对接,并能满足系统后期扩展的需要。一、医保数据上传医保数据上传是将......
  • 本地MinIO存储服务Java远程调用上传文件
    MinIO是一款高性能、分布式的对象存储系统,它可以100%的运行在标准硬件上,即X86等低成本机器也能够很好的运行MinIO。它的优点包括高性能、高可用性、易于部署和管理、支持多租户等。Cpolar内网穿透提供了更高的安全性和隐私保护,通过使用加密通信通道,Cpolar技术可以确保数据传输的......
  • Civil 3D使用COM API时对象版本号的查询方法
     查询对象版本有多种方法,方法一:在developer'sguide中查找,APIDeveloper'sGuide→AbouttheDeveloper'sGuide→NewFeaturesintheAutoCADCivil3DAPI→COMChanges这里有详细的介绍,不仅有当前的版本,还有上一版的版本号。方法二:在AutoCAD命令行中输入命令AeccVersio......
  • java注解
    一、java注解用于为java代码提供元数据。提供数据来解释程序代码。注解并非所解释的代码的一部分,不直接影响代码执行。所有注解会自动继承java.lang.annotation这个接口,所以不能再去继承别的接口或类。 解析一个类/方法的注解有2种方式:1、编译期的直接扫描编译器在对jav......
  • Java开发者的Python快速进修指南:文件操作
    Python提供的文件操作相对于Java来说,确实简单方便许多。不仅操作简单,代码可读性也相对较高。然而,我们需要注意的不仅仅是文件操作的简单性,还有文件操作的各种模式。在Java中,我们并不经常使用像Python中那样的操作模式。另外,我们还需要注意文件指针的移动。无论是Java还是Python,文......