hadoop reduce阶段 对象重用问题

问题根源:对象重用

Hadoop 为了优化性能,在 reduce 方法中会重用 keyvalue 对象。

这意味着,在 for(Person p : values) 循环中,变量 p 始终指向同一个 Person 对象实例。

框架在每次迭代时,会用新的数据覆盖 这个 Person 对象的内部属性,而不是创建一个新的对象。

因此,当你执行 plist.add(p) 时,你只是将同一个对象的引用 多次添加到了列表 plist 中。

最终,plist 里所有的元素都指向内存中的同一个 Person 对象,而这个对象的值是最后一次迭代时被覆盖的结果。

错误代码示例

假设 values 中包含三个 Person 对象,其 name 属性分别为 "Alice"、"Bob" 和 "Charlie"。

复制代码
List<Person> plist = new ArrayList<>();
for(Person p : values){
    plist.add(p);
}

执行后,plist 的内容将不是 ["Alice", "Bob", "Charlie"]。相反,plist 中会包含三个指向同一个对象 的引用,而这个对象的 name 属性是 "Charlie" 。所以,遍历 plist 会得到 ["Charlie", "Charlie", "Charlie"]

正确的解决方案

你需要创建一个新的 Person 对象副本,然后将副本添加到列表中。这样,列表中的每个元素都是一个独立的对象。

方法一:手动创建新对象并复制属性

这是最直接的方法,适用于所有情况。

复制代码
List<Person> plist = new ArrayList<>();
for(Person p : values){
    // 创建一个新的Person对象
    Person newPerson = new Person();
    // 手动复制所有需要的属性
    newPerson.setName(p.getName());
    newPerson.setAge(p.getAge());
    // ... 复制其他属性
    // 将新对象的引用添加到列表中
    plist.add(newPerson);
}
方法二:使用工具类复制属性

如果你的 Person 类有很多属性,可以使用像 Apache Commons BeanUtils 这样的工具类来简化属性复制过程。

复制代码
import org.apache.commons.beanutils.BeanUtils;

List<Person> plist = new ArrayList<>();
for(Person p : values){
    Person newPerson = new Person();
    try {
        // 自动复制所有同名同类型的属性
        BeanUtils.copyProperties(newPerson, p);
    } catch (Exception e) {
        e.printStackTrace();
    }
    plist.add(newPerson);
}
方法三:实现拷贝构造函数

在你的 Person 类中定义一个拷贝构造函数,可以使代码更简洁。

复制代码
public class Person implements Writable {
    private String name;
    private int age;

    // 默认的无参构造函数(Hadoop序列化需要)
    public Person() {}

    // 拷贝构造函数
    public Person(Person other) {
        this.name = other.name;
        this.age = other.age;
    }

    // ... 其他代码 (getter, setter, write, readFields)
}

然后在 reduce 方法中这样使用:

复制代码
List<Person> plist = new ArrayList<>();
for(Person p : values){
    // 使用拷贝构造函数创建副本
    plist.add(new Person(p));
}
相关推荐
海上小飞龙6 分钟前
分布式和微服务,一次讲清
分布式·微服务·架构
无风听海12 分钟前
深入解析 Elasticsearch 的 match_phrase_prefix与 match_bool_prefix
大数据·elasticsearch·mybatis
火眼金睛炼单词24 分钟前
初三冲刺单词工艺解析:从入门到精通
大数据
蓝速科技30 分钟前
蓝速科技 F100 双屏翻译机:中小企业跨国会议提效方案
大数据·网络·数据结构·人工智能·科技·运维开发
2601_9676598838 分钟前
GEO 优化哪家好推荐即搜 ai:2026 企业 AI 搜索获客服务商深度测评
大数据·人工智能
计算机源码社43 分钟前
基于Hadoop+Spark的黄金市场历史数据特征分析与可视化大屏 基于K-Means聚类算法的黄金历史价格阶段划分研究
大数据·hadoop·python·数据挖掘·数据分析·spark·毕业设计
IT毕设实战小研1 小时前
基于大数据的股票历史行情数据分析与可视化
大数据·信息可视化·数据挖掘·数据分析·课程设计
(Charon)1 小时前
【Kafka】消息队列学习(二):Topic、Partition与Offset,消息到底存在哪里
分布式·学习·kafka
IT研究室1 小时前
最新大数据毕业设计选题推荐-基于大数据的广州市美食店铺数据可视化分析-大数据-Spark-Hadoop-Bigdata
大数据·课程设计·美食
跨境小彭1 小时前
Temu 广告投放实操:ROAS 底层逻辑与批量广告作业方案
大数据·人工智能·自动化·temu