Reduce中Iterable迭代器K,V对象复用机制

apache官网对于reduce中k,v复用的描述如下:

The framework calls this method for each <key, (list of values)> pair in the grouped inputs. Output values must be of the same type as input values. Input keys must not be altered. The framework will reuse the key and value objects that are passed into the reduce, therefore the application should clone the objects they want to keep a copy of. In many cases, all values are combined into zero or one value.

框架为分组输入中的每个<key, (list of values)>对调用此方法。输出值必须与输入值具有相同的类型。输入键不能改变。框架将复用传递给reduce的key和 value对象,因此应用程序应该克隆当前希望保留副本的对象。在许多情况下,所有的值都合并为0或一个值。

apache官网文档链接: http://hadoop.apache.org/docs/r2.8.2/api/org/apache/hadoop/mapred/Reducer.html

Java源码中Reducer类下的reduce方法定义:

protected void reduce(KEYIN key, Iterable<VALUEIN> values, Context context
                        ) throws IOException, InterruptedException {
    for(VALUEIN value: values) {
      context.write((KEYOUT) key, (VALUEOUT) value);
    }
  }

复用原理:
先了解下Java引用类型创建和存储机制:引用其实就是一个地址,放在栈内存中,实际存储的东西会放在堆内存中。引用中的地址是实际存储的东西的首地址
所以reduce方法中 value只在使用前时被创建一次,在内存中分配一个地址(假设为0x0001),而在此后循环时,每次都从0x0001将上次放入的值取出,再放入新的值。
假设for循环中只存在一个 list.add(value) 语句(如下代码块),就相当于每次循环都将固定0x0001地址的value放入list集合,当在for循环结束时,集合list中的所有value元素的地址指向的都是0x0001,而此时0x0001只存放着最后一次循环的值。
例一:

reduce的Iterable迭代器中的内容是a,b,c这三条,然后把这三条数据加入到List中,然后遍历List的时候发现显示的结果是c,c,c

public class MyReducer extends Reducer<LongWritable, Text,LongWritable,Text> {
	
	ArrayList<Strnig> str = new ArrayList<Strnig>();
	
    @Override
    protected void reduce(LongWritable key, Iterable<String> values, Context context) {
        for (String value : values) {
            str.add(value);
        }
		v = str;		//集合中的value全都相等,都等于Iterable迭代器中最后一个值
		context.write(k,v);
    }
	
}

例二:

reduce的Iterable迭代器中的内容是a,b,c这三条,先把value赋值给val,然后把val加入到List中,最后遍历List的时候发现显示的结果是a,b,c

public class MyReducer extends Reducer<LongWritable, Text,LongWritable,Text> {
    @Override
    protected void reduce(LongWritable key, Iterable<String> values, Context context) {
		
		ArrayList<Strnig> str = new ArrayList<Strnig>();
		
        for (String value : values) {
			String val = new String();
			BeanUtils.copyProperties(val, value);
			str.add(val);
        }
		v = str;  //集合中的value一一对应Iterable中的值
		context.write(k,v);
    }
	
}

————————————————
版权声明:本文为博主的原创文章,转载请附上原文出处链接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天写代码了没

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值