您的位置:

Java8Stream优雅操作数据

Java Stream是Java 8中添加的新特性,它提供了一种全新的、优雅的方式来操作数据集合。这种方式可以让我们避免使用迭代器等重复性代码,而是使用更加易于理解和维护的函数式编程的方式来处理数据。Java Stream能够对集合进行过滤、排序、映射等操作,同时还可以支持多线程处理。本文将介绍Java Stream的使用方法,并展示如何使用Java Stream来优雅地处理数据。

一、Stream的基本概念

Stream是一个用于处理集合的标准化操作的概念。其本质是对数据源的一系列操作封装成一条流水线,类似于一条流水线上的清洗、加工、包装等工作,最终生成一个处理完成的结果。Stream表示数据流,和集合使用类似,但在某些情况下,Stream更胜一筹。Stream只是一个声明式的概念,不会改变数据源的元素,产生的结果也仅限于终止操作。使用Stream,可以大大减少程序的复杂性和代码冗余。

1.1 Stream的初步创建方法

Stream可以有两种创建方式,一种是通过集合或数组的Stream()方法进行创建,一种是通过Stream.of()方法传入一系列元素进行创建。Stream可以看成是一个元素的集合,每次对元素集合的操作都会返回一个新的元素集合。下面是通过数组和集合创建Stream的示例:

public class StreamTest {
    public static void main(String[] args) {
        // 通过数组创建Stream
        int[] nums = {1, 3, 5, 7, 9};
        IntStream stream = Arrays.stream(nums);
        System.out.println("通过数组创建Stream");
        stream.forEach(System.out::println);

        // 通过集合创建Stream
        List
    words = new ArrayList<>();
        words.add("mina");
        words.add("momo");
        words.add("sana");
        Stream
     stream1 = words.stream();
        System.out.println("通过集合创建Stream");
        stream1.forEach(System.out::println);
    }
}
    
   

1.2 Stream的中间操作方法

Stream提供了多种中间操作方法,这些方法可以看做是在Stream生成的元素集合上的一些处理操作,中间操作方法执行完毕后,仍可以执行后续的操作,这些方法不生成真正的处理结果,直到执行终止操作才会生成。下面是一些常见的中间操作方法:

filter方法

filter方法可以接收一个Predicate参数,用于对元素集合进行过滤操作,只有符合条件的元素才能进入下一步操作。下面的代码片段展示了使用filter方法过滤出大于3的数字:

// Filer示例
List
    list = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).filter(num -> num > 3).collect(Collectors.toList());

System.out.println("Filter示例");
list.forEach(System.out::println); //输出4,5,6,7,8,9

   
map方法

map方法可以接收一个Function参数,用于对元素集合进行映射操作,返回一个新的元素集合。下面的代码片段展示了使用map方法将字符串转成大写形式:

// Map示例
List
    list = Stream.of("hello", "world", "mina").map(String::toUpperCase).collect(Collectors.toList());

System.out.println("Map示例");
list.forEach(System.out::println); //输出HELLO,WORLD,MINA

   
flatMap方法

flatMap方法可以接收一个Function参数,用于将多个元素集合合并成一个新的元素集合。下面的代码片段展示了使用flatMap方法将多个集合合并成一个新的集合:

// FlatMap示例
List
    list1 = Arrays.asList(1, 2, 3);
List
     list2 = Arrays.asList(4, 5, 6);
List
      list3 = Arrays.asList(7, 8, 9);

List
       list = Stream.of(list1, list2, list3).flatMap(Collection::stream).collect(Collectors.toList());
System.out.println("FlatMap示例");
list.forEach(System.out::println); //输出1,2,3,4,5,6,7,8,9

      
     
    
   
distinct方法

distinct方法用于去重,对于某些数据处理场景来说十分有用。下面的代码片段展示了对元素集合进行去重操作的方法:

// Distinct示例
List
    list = Stream.of(1, 2, 3, 2, 1, 5, 4, 3).distinct().collect(Collectors.toList());

System.out.println("Distinct示例");
list.forEach(System.out::println); //输出1,2,3,5,4

   

1.3 Stream的结束操作方法

结束操作方法是对元素集合进行终止处理的方法,这些方法执行后会生成真正的处理结果。Stream提供了多种结束操作方法,最常见的是forEach和collect方法。

forEach方法

forEach方法可以对元素集合进行遍历操作,并对每个元素执行指定的操作。下面的代码片段展示了使用forEach方法打印元素集合中的所有元素:

// ForEach示例
Stream.of("apple", "banana", "orange").forEach(System.out::println);

collect方法

collect方法可以将Stream的处理结果收集到一个集合中。下面的代码片段展示了使用collect方法将Stream处理结果收集到一个列表中:

// Collect示例
List
    list = Stream.of("apple", "banana", "orange").collect(Collectors.toList());

System.out.println("Collect示例");
list.forEach(System.out::println); //输出apple,banana,orange

   

二、Stream的优雅操作数据

Stream的特点就在于它提供了一种更加简洁、易于理解和维护的方式操作数据。在实际使用中,Stream可以用于各种数据集合的操作,无论是数组、集合还是数据库操作,Stream都可以通过优雅的方式实现,从而使程序变得更加高效、简洁。

2.1 Stream在集合操作中的应用

Stream可以与集合操作结合使用,实现各种集合的处理操作,使集合的操作变得更加简单、高效。下面是一些在集合操作中使用Stream的常用方法示例:

filter方法实现集合过滤

集合过滤操作是Stream在实际应用中最常用的操作之一。可以使用filter方法实现简单的过滤操作。下面的代码展示了如何使用filter方法过滤集合中的元素:

public class StreamTest {
    public static void main(String[] args) {
        List
    list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);

        // 过滤出大于3的元素
        List
     filteredList = list.stream().filter(num -> num > 3).collect(Collectors.toList());

        System.out.println("Filter示例");
        filteredList.forEach(System.out::println); //输出4,5,6
    }
}
    
   
map方法实现集合转换

集合转换操作是Stream在实际应用中的另一种常见操作,可以使用map方法将集合中的元素转换为另一种类型的元素,达到转换集合类型的效果。下面的代码展示了如何使用map方法将集合中的元素整数转换成字符串形式:

public class StreamTest {
    public static void main(String[] args) {
        List
    list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);

        // 将元素转换为字符串并收集为一个List
        List
     strList = list.stream().map(num -> num.toString()).collect(Collectors.toList());

        System.out.println("Map示例");
        strList.forEach(System.out::println); //输出1,2,3,4,5,6
    }
}
    
   
reduce方法实现集合归约

集合归约操作是Stream中比较复杂的一种操作,可以使用reduce方法将集合中的元素归约成一个值。下面的代码展示了如何使用reduce方法将集合中的元素相加:

public class StreamTest {
    public static void main(String[] args) {
        List
    list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);

        Optional<Integer> sum = list.stream().reduce((num1, num2) -> num1 + num2);

        System.out.println("Reduce示例");
        System.out.println(sum.get()); //输出21
    }
}
   

2.2 Stream在数据库操作中的应用

应用程序在处理大型数据集时经常需要进行数据库操作。在Java中,我们通常使用JDBC来操作数据库。使用Stream可以更加优雅地处理数据库数据。下面是一个使用Stream进行数据库操作的示例:

// 数据库Student表有id,name,age三个字段
public class StreamTest {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
        String name = "root";
        String password = "root";

        // 创建数据源
        DataSource dataSource = null;
        try {
            dataSource = DruidDataSourceFactory.createDataSource(new Properties() {{
                setProperty("driverClassName", "com.mysql.jdbc.Driver");
                setProperty("url", url);
                setProperty("username", name);
                setProperty("password", password);
            }});
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 从数据库中查询结果并使用Stream对结果进行处理
        try (Connection conn = dataSource.getConnection()) {
            PreparedStatement prepStatement = conn.prepareStatement("SELECT * FROM Student");
            ResultSet resultSet = prepStatement.executeQuery();

            List<Student> students = new ArrayList<>();
            while (resultSet.next()) {
                Student student = new Student();
                student.setId(resultSet.getInt("id"));
                student.setName(resultSet.getString("name"));
                student.setAge(resultSet.getInt("age"));
                students.add(student);
            }

            // 使用Stream从查询结果中过滤出年龄大于18岁的学生
            List<String> names = students.stream().filter(student -> student.getAge() > 18).map(Student::getName).collect(Collectors.toList());

            System.out.println("JDBC + Stream示例");
            names.forEach(System.out::println); //输出年龄大于18岁的学生姓名列表
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

// Student类
public class Student {
    private Integer id;
    private String name;
    private Integer age;

    // TODO: Setter & Getter方法
}

三、总结

Stream是一种全新的、优雅的方式来操作数据集合,相比于传统的操作方式,Stream拥有更好的可读性、可维护性和性能。Stream可以用于处理各种类型的数据集合,包括数组、集合和数据库中的数据。在实际应用中,Stream可以提高代码的可读性、可维护性和代码的重用性,从而提高开发的效率。