起初遍历values时直接把对象添加到集合中,后来输出结果和预期不符,debug时发现添加到集合中的对象的值全部是最后一个对象的值,网上百度了下,发现是reduce阶段对象重用的问题,reduce阶段的key,value分别指向一个对象,无论操作了多少个键值对,始终是这两个对象,而ArrayList的add()添加的是对象的引用而不是对象的值,所以如果想要保存key,value的值(属性),需要重新new一个对象进行保存,需要添加到集合中的,应当先new一个对象,拷贝属性后再添加到集合中,不能把直接key,value添加到集合中(除非你的迭代器中只有一个值)
具体可以参考https://my.oschina.net/leejun2005/blog/131744
1 protected void reduce(Text key, Iterable<TableBean> value, 2 Reducer<Text, TableBean, TableBean, NullWritable>.Context context) throws IOException, InterruptedException { 3 4 List<TableBean> orderBeanList = new ArrayList<TableBean>(); 5 TableBean pdBean = new TableBean(); 6 7 //分拣存储 8 for (TableBean tableBean : value) { 9 String name = tableBean.getpName(); 10 if(StringUtils.isBlank(name)) { 11 TableBean bean = new TableBean(); 12 try { 13 BeanUtils.copyProperties(bean, tableBean); 14 } catch (IllegalAccessException e) { 15 e.printStackTrace(); 16 } catch (InvocationTargetException e) { 17 e.printStackTrace(); 18 } 19 //orderBean 20 orderBeanList.add(bean); 21 }else { 22 try { 23 BeanUtils.copyProperties(pdBean, tableBean); 24 } catch (IllegalAccessException e) { 25 e.printStackTrace(); 26 } catch (InvocationTargetException e) { 27 e.printStackTrace(); 28 } 29 } 30 } 31 32 //遍历集合进行合并 33 for (TableBean tableBean : orderBeanList) { 34 tableBean.setpName(pdBean.getpName()); 35 //写出 36 context.write(tableBean,NullWritable.get()); 37 } 38 39 }
原文地址:https://www.cnblogs.com/tele-share/p/9674633.html
时间: 2024-10-05 04:56:16