首页 > Java > java教程 > 正文

Java中复杂对象列表的扁平化转换:将多事务支付对象拆分为单事务支付对象

聖光之護
发布: 2025-10-22 11:51:01
原创
447人浏览过

Java中复杂对象列表的扁平化转换:将多事务支付对象拆分为单事务支付对象

本文详细介绍了在java中如何将包含嵌套列表(如支付对象中包含多个交易列表)的复杂对象列表进行转换。目标是将每个原始对象根据其嵌套列表中的元素进行展平,生成一个新列表,其中每个新对象仅包含一个嵌套元素,同时保留原始对象的其他属性。文章将通过java 7、java 8-15以及java 16及更高版本提供的不同编程范式进行演示,帮助开发者高效地处理此类数据结构转换。

软件开发中,我们经常需要处理复杂的数据结构,其中一个常见场景是对象内部包含一个嵌套的列表。例如,一个支付对象(Pmt)可能包含多个交易(Transaction)记录。然而,在某些业务逻辑或数据处理需求下,我们可能需要将这种一对多的关系“展平”为一对一的关系,即为每个嵌套的交易记录创建一个独立的支付对象副本,同时保留原始支付对象的其他属性。

场景描述

假设我们有以下两个Java类定义:

public class A {
    String a;
    String b;
    String v;
    List<Pmt> pmtList; // 包含支付对象列表
    // ... 其他属性和方法
}

public class Pmt {
    String id; // 支付ID
    String b;  // 其他支付属性
    List<Transaction> trList; // 嵌套的交易列表
    // ... 其他属性和方法

    // 构造函数示例,用于创建新的Pmt对象
    public Pmt(String id, String b, List<Transaction> trList) {
        this.id = id;
        this.b = b;
        this.trList = trList;
    }

    // Getter方法
    public String getId() { return id; }
    public String getB() { return b; }
    public List<Transaction> getTrList() { return trList; }
}

public class Transaction {
    // 交易的详细信息
    // ... 属性和方法
}
登录后复制

我们的目标是,给定一个 List<Pmt>,将其转换为一个新的 List<Pmt>,使得新列表中的每个 Pmt 对象仅包含一个 Transaction。这意味着如果一个原始 Pmt 对象包含 N 个 Transaction,那么它将被转换为 N 个新的 Pmt 对象,每个新对象都拥有原始 Pmt 的所有属性,但其 trList 中只包含一个 Transaction。

例如,如果原始列表中有 5 个 Pmt 对象,每个 Pmt 对象包含 2 个 Transaction,那么新列表将包含 10 个 Pmt 对象。

立即学习Java免费学习笔记(深入)”;

解决方案

以下将介绍三种在不同Java版本中实现此转换的方法。为了使这些解决方案生效,Pmt 类需要一个合适的构造函数,能够接收原始 Pmt 的属性以及一个包含单个 Transaction 的列表。例如,可以添加如下构造函数:

import static java.util.Collections.singletonList; // 静态导入,方便创建单元素列表

public class Pmt {
    // ... 现有属性和方法

    public Pmt(String id, String b, List<Transaction> trList) {
        this.id = id;
        this.b = b;
        this.trList = trList;
    }
}
登录后复制

1. Java 7 及更早版本(或兼容性方案)

在Java 7及更早的版本中,通常使用传统的迭代循环来实现此类转换。通过嵌套的 forEach 循环,我们可以遍历每个支付对象及其内部的交易列表,并为每个交易创建一个新的支付对象。

import java.util.ArrayList;
import java.util.List;
import static java.util.Collections.singletonList;

public class PmtTransformer {

    public List<Pmt> transformPmtListJava7(List<Pmt> pmtList) {
        List<Pmt> newList = new ArrayList<>();
        for (Pmt p : pmtList) {
            for (Transaction tr : p.getTrList()) {
                // 为每个交易创建一个新的Pmt对象,并将其添加到新列表中
                newList.add(new Pmt(p.getId(), p.getB(), singletonList(tr)));
            }
        }
        return newList;
    }
}
登录后复制

说明: 这种方法直观易懂,通过两层循环,外层遍历 pmtList 中的每个 Pmt 对象,内层遍历当前 Pmt 对象中的 trList。对于 trList 中的每个 Transaction,我们都创建一个新的 Pmt 对象,其中包含原始 Pmt 的 id 和 b 属性,以及一个只包含当前 Transaction 的新列表。

2. Java 8 - Java 15(Stream API 结合 flatMap)

Java 8引入的Stream API为集合操作提供了更声明式和函数式的方法。flatMap 操作特别适合处理这种一对多的转换场景。它能够将一个流中的每个元素转换成零个、一个或多个元素的流,然后将这些流连接成一个单一的流。

标书对比王
标书对比王

标书对比王是一款标书查重工具,支持多份投标文件两两相互比对,重复内容高亮标记,可快速定位重复内容原文所在位置,并可导出比对报告。

标书对比王58
查看详情 标书对比王
import java.util.List;
import java.util.stream.Collectors;
import static java.util.Collections.singletonList;

public class PmtTransformer {

    public List<Pmt> transformPmtListJava8(List<Pmt> pmtList) {
        return pmtList.stream()
                .flatMap(p -> p.getTrList().stream() // 将每个Pmt对象的trList转换为Transaction流
                                .map(tr -> new Pmt(p.getId(), p.getB(), singletonList(tr)))) // 为每个Transaction创建新的Pmt对象
                .collect(Collectors.toList()); // 收集结果到新的List中
    }
}
登录后复制

说明:

  1. pmtList.stream():将原始 Pmt 列表转换为一个 Pmt 对象的流。
  2. .flatMap(p -> ...):对于流中的每个 Pmt 对象 p:
    • p.getTrList().stream():获取 p 内部的 trList,并将其转换为一个 Transaction 对象的流。
    • .map(tr -> new Pmt(p.getId(), p.getB(), singletonList(tr))):对于这个 Transaction 流中的每个 tr,创建一个新的 Pmt 对象。这个新的 Pmt 对象会复制原始 p 的 id 和 b 属性,但其 trList 只包含当前的 tr。
    • flatMap 会将所有这些内部生成的 Pmt 对象流扁平化为一个单一的 Pmt 对象流。
  3. .collect(Collectors.toList()):将最终的 Pmt 对象流收集到一个新的 List<Pmt> 中。

3. Java 16 及更新版本(Stream API 结合 mapMulti)

Java 16引入了 mapMulti 方法,它提供了一种更灵活、可能更高效的方式来处理一对多(或多对多)的流转换,尤其是在需要更精细控制或避免创建中间流时。它允许通过一个 Consumer 回调函数来发出零个、一个或多个元素。

import java.util.List;
import java.util.function.Consumer;
import static java.util.Collections.singletonList;

public class PmtTransformer {

    public List<Pmt> transformPmtListJava16(List<Pmt> pmtList) {
        return pmtList.stream()
                .<Pmt>mapMulti((Pmt p, Consumer<Pmt> c) -> { // 对每个Pmt对象进行操作
                    p.getTrList().forEach(tr ->
                        c.accept(new Pmt(p.getId(), p.getB(), singletonList(tr)))); // 为每个Transaction发出一个Pmt对象
                })
                .toList(); // Java 16+ 提供的便捷方法,直接收集为不可变列表
    }
}
登录后复制

说明:

  1. pmtList.stream():与Java 8方案相同,创建 Pmt 对象的流。
  2. .<Pmt>mapMulti((Pmt p, Consumer<Pmt> c) -> { ... }):
    • mapMulti 接收一个 BiConsumer,其中第一个参数是当前流元素(Pmt p),第二个参数是一个 Consumer<Pmt> c。
    • 在这个 BiConsumer 内部,我们遍历 p.getTrList()。
    • 对于每个 Transaction tr,我们调用 c.accept(new Pmt(...)) 来将新创建的 Pmt 对象“发出”到下游流中。
    • mapMulti 会将所有这些发出的元素组合成一个单一的流。
  3. .toList():这是Java 16引入的一个便捷方法,用于将流中的所有元素收集到一个新的不可变 List 中。

总结

本文详细介绍了在Java中将包含嵌套列表的对象进行展平转换的三种主要方法。

  • Java 7 及更早版本:使用传统的嵌套 for 循环,代码直观,易于理解,但在处理大量数据时可能不如Stream API简洁。
  • Java 8 - Java 15:利用Stream API的 flatMap 方法,实现了声明式的数据转换。这种方式代码简洁,可读性强,是现代Java开发中处理此类场景的推荐方法。
  • Java 16 及更新版本:引入了 mapMulti,为一对多转换提供了更灵活的控制,并且在某些情况下可能提供更好的性能,因为它避免了创建中间流。同时,toList() 方法进一步简化了收集操作。

选择哪种方法取决于您的项目所使用的Java版本以及个人偏好。对于新项目,推荐使用Java 8或更高版本的Stream API,以享受其带来的简洁性和表达力。无论选择哪种方法,核心思想都是遍历嵌套列表,并为每个子元素创建原始对象的一个新副本,从而实现数据的展平。

以上就是Java中复杂对象列表的扁平化转换:将多事务支付对象拆分为单事务支付对象的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号