当前位置: 首页 > article >正文

用 Lambda 表达式处理 Java Stream 流操作

在 Java 编程领域,Lambda 表达式与 Stream API 的组合堪称一对强大的搭档,极大地简化了集合数据处理的过程。本文将深入探讨如何借助 Lambda 表达式实现各种常见的 Stream 流操作。

List 转 Set

将 List 转换为 Set 是去除重复元素的便捷方式。利用 Stream 流,代码如下:

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

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

        Set<Integer> set = list.stream()
              .collect(Collectors.toSet());

        System.out.println(set);
    }
}

通过stream()方法创建流,再使用collect(Collectors.toSet())将流中的元素收集到 Set 中,Set 的特性会自动剔除重复元素。

 

List 转 Map

当我们有一个对象 List,想以对象的某个属性为键构建 Map 时,可这样操作:

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

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;
    }
}

public class ListToMapExample {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("Alice", 25));
        personList.add(new Person("Bob", 30));

        Map<String, Person> personMap = personList.stream()
              .collect(Collectors.toMap(Person::getName, p -> p));

        System.out.println(personMap);
    }
}

Collectors.toMap()的第一个参数指定键的提取方式,这里是Person::getName,第二个参数p -> p表示值就是对象本身。

Map 转 List

把 Map 的键值对转换为 List,能方便后续对键值对进行统一处理:

 

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

public class MapToListExample {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("key1", 1);
        map.put("key2", 2);

        List<Map.Entry<String, Integer>> entryList = map.entrySet()
              .stream()
              .collect(Collectors.toList());

        System.out.println(entryList);
    }
}

先通过entrySet()获取键值对集合,再用 Stream 流和collect(Collectors.toList())将其收集为 List。

过滤、求和与分组

(一)过滤:筛选符合条件元素

从 List 中筛选出偶数 此时我们会借助.filter方法:

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

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

        List<Integer> evenList = list.stream()
              .filter(num -> num % 2 == 0)
              .collect(Collectors.toList());

        System.out.println(evenList);
    }
}

(二)求和:计算数值总和

对 List 中的整数求和:

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

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

        int sum = list.stream()
              .mapToInt(Integer::intValue)
              .sum();

        System.out.println(sum);
    }
}

mapToInt()将 Integer 流转换为 IntStream,再用sum()方法计算总和。

分组:按特定属性归类

对 Person 对象按年龄分组:

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

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;
    }
}

public class GroupingExample {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("Alice", 25));
        personList.add(new Person("Bob", 25));
        personList.add(new Person("Charlie", 30));

        Map<Integer, List<Person>> groupedMap = personList.stream()
              .collect(Collectors.groupingBy(Person::getAge));

        System.out.println(groupedMap);
    }
}

map 与 reduce:元素转换与累积

(一)map:元素映射转换

将字符串 List 中的元素转为大写:

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

public class MapExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("world");

        List<String> upperList = list.stream()
              .map(String::toUpperCase)
              .collect(Collectors.toList());

        System.out.println(upperList);
    }
}

map()方法根据 Lambda 表达式String::toUpperCase将每个元素进行转换。

(二)reduce:元素累积操作

reduce 是一个用于对流中的元素进行累积操作的终端操作(Terminal Operation)。它的主要作用是将流中的元素组合成一个单个的值,通过指定的二元操作符(Binary Operator)来不断地将元素进行合并和累积。

reduce 方法的传参情况
两个参数

这种形式的 reduce 方法签名如下:

<U> U reduce(U identity, BinaryOperator<U> accumulator)
  • 参数说明
    • identity:初始值,也称为 “标识值”。它是一个与流中元素类型兼容的初始对象,在累积操作开始时作为起始点。如果流为空,reduce 操作会直接返回这个初始值。
    • accumulator:一个二元操作符,是一个 BinaryOperator<U> 类型的函数。它接受两个参数,第一个参数是累积结果(从初始值开始),第二个参数是流中的元素,用于将流中的元素逐步累积到结果中。
 一个参数
Optional<T> reduce(BinaryOperator<T> accumulator)
  • 参数说明
    • accumulator:同样是一个二元操作符,用于将流中的元素两两组合,逐步累积得到最终结果。
计算整数 List 中所有元素的乘积
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

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

        Optional<Integer> product = list.stream()
              .reduce((a, b) -> a * b);

        product.ifPresent(System.out::println);
    }
}

reduce()方法按照 Lambda 表达式(a, b) -> a * b对元素进行累积计算。

查找最大值或最小值
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

public class FindMaxWithReduce {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        Optional<Integer> max = numbers.stream()
               .reduce((a, b) -> a > b? a : b);

        if (max.isPresent()) {
            System.out.println("Max: " + max.get());
        }
    }
}
连接字符串

对于一个包含字符串的 Stream,可以使用 reduce 来连接所有的字符串。

import java.util.Arrays;
import java.util.List;

public class ConcatenateStringsWithReduce {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("Hello", "World", "Java", "Stream");

        String result = words.stream()
               .reduce("", (accumulator, word) -> accumulator + word);

        System.out.println("Concatenated String: " + result);
    }
}

Lambda 表达式和 Stream API 的结合,为 Java 开发者提供了简洁高效的数据处理方式,熟练运用这些操作,能让代码更加优雅和易维护。


http://www.kler.cn/a/538034.html

相关文章:

  • 增量hdfs数据追平
  • idea Ai工具通义灵码,Copilot我的使用方法以及比较
  • C#中的Frm_Welcome.Instance.Show(),是什么意思
  • 等级保护2.0|网络安全服务
  • IDEA编写SpringBoot项目时使用Lombok报错“找不到符号”的原因和解决
  • 在CT107D单片机综合训练平台上,8个数码管分别单独依次显示0~9的值,然后所有数码管一起同时显示0~F的值,如此往复。
  • 装备库室管控系统|支持国产化、自主研发
  • 【医院运营统计专题】2.运营统计:医院管理的“智慧大脑”
  • 【Milvus】向量数据库pymilvus使用教程
  • 2022java面试总结,1000道(集合+JVM+并发编程+Spring+Mybatis)的Java高频面试题
  • Vue | 透传 Attributes(非 prop 的 attribute )
  • STM32 硬件I2C读写MPU6050
  • V8 GC垃圾回收
  • 一步一步生成音乐类小程序的详细指南,结合AI辅助开发的思路
  • android studio无痛入门
  • 西安科技创新领跑者:树莓集团以科技创新赋能产业生态圈
  • Milvus 存储设计揭秘:从数据写入到 Segment 管理的全链路解析
  • 深入浅出Log4j2:从入门到实战应用指南
  • C语言基础系列【6】流程控制
  • 快速建立私有化知识库(私有化训练DeepSeek,通过ollama方式)
  • python 使用OpenAI Whisper进行显卡推理语音翻译
  • 探秘树莓集团海南战略:文创领军者的市场破局之路
  • 【Go语言快速上手】第二部分:Go语言进阶
  • opencv打开摄像头出现读取帧错误问题
  • 原子核链式反应与曼哈顿计划
  • 【docker】Failed to allocate manager object, freezing:兼容兼容 cgroup v1 和 v2