找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

474

积分

0

好友

59

主题
发表于 7 天前 | 查看: 24| 回复: 0

在日常的 Java 编码实践中,经常会遇到一个方法需要返回多个值的情况。例如,执行一个操作后,不仅要返回操作结果,还需附带状态码或额外描述信息。传统的解决方案,例如创建一个专用的数据传输对象(DTO)或使用 Map 集合,虽然可行,但往往会增加代码的复杂度,使调用方难以直观地理解和使用这些返回值。

此时,来自 Apache Commons Lang3 工具库的 org.apache.commons.lang3.tuple 包下的 PairTriple 类就成了简洁高效的替代方案。它们为管理和传递多个关联值提供了标准化的方式,能显著提升代码的清晰度和可维护性,是Java开发中处理简单数据组的实用工具。

引入依赖

使用 PairTriple 前,需在项目中引入 Apache Commons Lang3 库的依赖。在 Maven 项目中,于 pom.xml 文件中添加如下配置:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

Pair 类:便捷的键值对容器

Pair 类概述

Pair 是一个表示简单键值对的抽象类。它实现了 Map.Entry 接口,因此可以无缝用于各种集合操作;同时实现了 Comparable 接口,支持对象间的比较;并且它也是可序列化的。

以下是 Pair 类的部分核心源码:

public abstract class Pair<L, R> implements Map.Entry<L, R>, Comparable<Pair<L, R>>, Serializable {
    public static <L, R> Pair<L, R> of(L left, R right) {
        return ImmutablePair.of(left, right);
    }
    public static <L, R> Pair<L, R> of(Map.Entry<L, R> pair) {
        return ImmutablePair.of(pair);
    }
    public final L getKey() {
        return this.getLeft();
    }
    public abstract L getLeft();
    public abstract R getRight();
    public R getValue() {
        return this.getRight();
    }
}

Pair 类有两个直接的实现子类:MutablePair(可变)和 ImmutablePair(不可变)。

MutablePair:可变的键值对

MutablePair 允许在对象创建后修改其“左值”(left)和“右值”(right),提供了灵活性。但需要注意,它是非线程安全的。

创建方式示例:

// 方式1:使用构造方法
MutablePair<String, Integer> pair1 = new MutablePair<>("Key", 100);
// 方式2:使用静态工厂方法 of
MutablePair<String, Integer> pair2 = MutablePair.of("Key", 100);
// 方式3:创建空对象后设置值
MutablePair<String, Integer> pair3 = new MutablePair<>();
pair3.setLeft("Key");
pair3.setRight(100);

其左值和右值成员变量是 public 的,可直接访问 (pair.left, pair.right) 或通过 setLeft/setRight 方法修改。

ImmutablePair:不可变的键值对

ImmutablePair 在创建后其值不可更改,因此是线程安全的。尝试调用其 setValue 方法会抛出 UnsupportedOperationException 异常。

创建方式示例:

// 方式1:使用构造方法
ImmutablePair<String, Integer> pair1 = new ImmutablePair<>("Key", 100);
// 方式2:使用静态工厂方法 of (推荐)
ImmutablePair<String, Integer> pair2 = ImmutablePair.of("Key", 100);
// 方式3:通过 Pair 的静态工厂方法 of (返回的也是 ImmutablePair)
Pair<String, Integer> pair3 = Pair.of("Key", 100);

其成员变量同样为 public final,确保了一旦赋值便不可变。

Pair 使用示例

假设有一个 UserDO 类,我们定义一个方法根据用户ID查询用户信息并返回一个状态码。

class UserDO {
    private String userId;
    private Integer age;
    // 省略getter/setter
}

// 业务方法:返回用户信息和查询状态
public Pair<UserDO, Integer> getUserInfoWithStatus(String userId) {
    UserDO user = userDao.selectById(userId);
    Integer status = (user != null) ? 200 : 404; // 200找到,404未找到
    // 使用不可变Pair,确保返回结果不被意外修改
    return ImmutablePair.of(user, status);
}

// 调用方
Pair<UserDO, Integer> result = getUserInfoWithStatus("123");
UserDO user = result.getLeft();
Integer statusCode = result.getRight();
// 或者使用 Map.Entry 接口定义的方法
UserDO user = result.getKey();
Integer statusCode = result.getValue();

// 尝试修改 ImmutablePair 的值会抛出异常
// result.setValue(500); // UnsupportedOperationException

Triple 类:强大的三元组工具

Triple 类概述

Triple 是一个用于表示三元组的抽象类,包含左(Left)、中(Middle)、右(Right)三个有序元素。它适用于需要返回三个紧密关联值的场景,避免了为简单组合而创建专门类的麻烦。

以下是 Triple 类的部分源码:

public abstract class Triple<L, M, R> implements Comparable<Triple<L, M, R>>, Serializable {
    public static <L, M, R> Triple<L, M, R> of(final L left, final M middle, final R right) {
        return new ImmutableTriple<>(left, middle, right);
    }
    public abstract L getLeft();
    public abstract M getMiddle();
    public abstract R getRight();
}

Triple 同样有 MutableTripleImmutableTriple 两个子类。

MutableTriple:可变的三元组

MutableTriple 提供了 setLeftsetMiddlesetRight 方法用于修改其元素值,是非线程安全的。

// 创建可变三元组
MutableTriple<String, Integer, Boolean> triple = MutableTriple.of("Test", 1, true);
triple.setMiddle(2); // 修改中间值

ImmutableTriple:不可变的三元组

ImmutableTriple 是其不可变版本,线程安全。其三个成员变量均被声明为 final

Triple 使用示例

考虑一个场景:执行一个批处理任务,需要返回成功数量、失败数量和总耗时。

class UserDO {
    private String userId;
    private String userName;
    private Integer sex;
    // 省略getter/setter
}

// 业务方法:批量处理用户,返回统计信息
public Triple<Integer, Integer, Long> batchProcessUsers(List<UserDO> users) {
    long startTime = System.currentTimeMillis();
    int success = 0;
    int failure = 0;

    for (UserDO user : users) {
        boolean result = processSingleUser(user);
        if (result) {
            success++;
        } else {
            failure++;
        }
    }

    long totalTime = System.currentTimeMillis() - startTime;
    // 返回不可变三元组
    return ImmutableTriple.of(success, failure, totalTime);
}

// 调用方
Triple<Integer, Integer, Long> stats = batchProcessUsers(userList);
int successCount = stats.getLeft();
int failureCount = stats.getMiddle();
long timeCost = stats.getRight();
System.out.printf("处理完成:成功%d条,失败%d条,耗时%dms%n", successCount, failureCount, timeCost);

总结

PairTriple 是 Apache Commons Lang3 中两个非常实用的工具类。它们通过提供标准化的轻量级容器,优雅地解决了方法多值返回的问题,减少了不必要的DTO类的创建,使代码意图更加清晰。ImmutablePairImmutableTriple 的不可变性也增强了代码在并发环境下的安全性。

编码实践中,合理运用这些工具类能够有效简化数据结构处理,提升代码的可读性和可维护性。对于简单的、临时性的数据组合(尤其是作为方法返回值或局部变量),它们是优于自定义类或 Map 的简洁选择。然而,对于具有复杂行为或需要持久化的领域模型,定义完整的类仍然是更合适的做法。




上一篇:TCP、HTTP与RPC深度解析:网络协议分层设计与微服务架构选型
下一篇:Cloudflare远程绑定本地开发实战指南:连接生产环境数据测试Worker代码
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-8 17:14 , Processed in 0.100883 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表