MapReduce简单编程详解(4):查找2012年美国人口最多的州,以及未满18岁人口最多的州;

  1. 查找2012年美国人口最多的州
//每行就运行一次map函数
public class WordCountMapper extends Mapper<LongWritable, Text, Text, DoubleWritable> {//?DoubleWritable

    @Override
    protected void map(LongWritable key, Text value, Context context)
            throws IOException, InterruptedException {
        // TODO Auto-generated method stub
        //super.map(key, value, context);
        String s=value.toString();
        String[] ws=s.split(",");
        
        String k="abc";//得到州名ws[0]
        if(!ws[0].equals(k)) {
        	k=ws[0];
        }
        
       if(ws[2].equals("2012") && !ws[0].equals("state")) {//跳过第一行state/region,ages,year,population,且选定“2012”
    	   //context.write(new Text(Text.valueOF), new DoubleWritable(Double.valueOf(ws[3])));
    	   context.write(new Text(ws[0]), new DoubleWritable(Double.valueOf(ws[3])));
       }
    }
}


public class WordCountReducer extends Reducer<Text, DoubleWritable, Text, DoubleWritable> {
	Map<String,Double> map=new HashMap<String, Double>();

    @Override
    protected void reduce(Text key, Iterable<DoubleWritable> values, Context context)
            throws IOException, InterruptedException {
        // TODO Auto-generated method stub
        // super.reduce(arg0, arg1, arg2);

        double sum = 0;//求每个州的成年人、未成年人的人数
                   
        for (DoubleWritable value : values) {
        	sum += value.get();
            }
        
 		/*用putIfAbsent()保存数据的时候,如果该链表中保存的有相同key的值,那么就不会对我们当前的value进行保存
  	 	  用put()存储数据的时候,不管是该链表中是否有当前需要存储的key都会保存,我们所要保存的当前key所对应的value*/      		
		  //Map<String,Double> map=new HashMap<String, Double>();不能放这里
		  map.put(key.toString(),sum);//[('AK',918469.0),('AL',5935017.0),('AR',3660299.0)...]
		 							 //key不变,但涉及存储问题,转换成String类型;value=sum
		         
        //context.write(new Text(key), new DoubleWritable(sum));这个输出的只是各个州的总人口,不能最多的
        //还需要再比较,即下面代码   
    }
    
    	@Override		//cleanup
    	protected void cleanup(Context context) throws IOException,InterruptedException{
		 List<Map.Entry<String,Double>> list=new LinkedList<Map.Entry<String,Double>>(map.entrySet()); 
		 	//Map.Entry:取键值、值的集合												//map.entrySet():整个键值对的集合,通过其得到
		 
		 //排序
		 Collections.sort(list, new Comparator<Map.Entry<String,Double>>(){
			 @Override
			 public int compare(Entry<String,Double> arg0,Entry<String,Double> arg1) {
				 return (int) (arg1.getValue()-arg0.getValue());
			 }
		 });
		 	for(int i=0;i<1;i++) {
		 		context.write(new Text("2012年人口最多的州:"+list.get(i).getKey()+"\n数量:"), 
		 				      new DoubleWritable(list.get(i).getValue()));
		 	}
	  }     
	 

}

代码分解:

protected void cleanup(Context context) throws IOException,InterruptedException{
		 List<Map.Entry<String,Double>> list=new LinkedList<Map.Entry<String,Double>>(map.entrySet()); 
		 	
		 Collections.sort(list, new Comparator<Map.Entry<String,Double>>(){
			 @Override
			 public int compare(Entry<String,Double> arg0,Entry<String,Double> arg1) {
				 return (int) (arg1.getValue()-arg0.getValue());
			 }
		 });

主要的比较:
如何给List集合排序Collections.sort(list,new Comparator)

延申的:
Collections.sort的2种用法

Java中Map的 entrySet() 详解以及用法(四种遍历map的方式)
Map.Entry的作用:
Map.Entry是为了更方便的输出map键值对。一般情况下,要输出Map中的key 和 value 是先得到key的集合keySet(),然后再迭代(循环)由每个key得到每个value。values()方法是获取集合中的所有值,不包含键,没有对应关系。而Entry可以一次性获得这两个值。

for(int i=0;i<1;i++) {
		 		context.write(new Text("2012年人口最多的州:"+list.get(i).getKey()+"\n数量:"), 
		 				      new DoubleWritable(list.get(i).getValue()));
		 	}

*cleanup函数以及排序

转换成List,以及list.get(i).getKey()取值的图在这里插入图片描述
未成年只改map这句

if (ws[2].equals("2012") && !ws[0].equals("state")  && ws[1].equals("under18") && !ws[0].equals("USA") )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值