您的位置:首页 > 其它

mapReduce原理浅析

2013-02-04 13:39 337 查看
我们以《Hadoop权威指南》这本书上的例子,来分析一下,MapReduce是如何工作的。

我们引用它分析气温的例子。这个例子还是非常经典的,我个人认为小缺点就是,没有对传统的程序是如何工作的进行对比,如果加入此项,它将是一个完美的东西,现在就让我们,来完美它。

手写我们写一段Java程序,实现相同的功能<分析1901年和1902年最高气温>,当然程序略加改动就可以分析最低气温,在改动一下,就可以高和低同时出现,废话了,呵呵。

这里需要使用气温的数据, 我会提供下载链接。

我们提出一行数据,看看,年份在哪里

0029029070999991901010106004+64333+023450FM-12+000599999V0202701N015919999999N0000001N9-00781+99999102001ADDGF108991999999999999999999

package org.pcwl;

/**

 * @author QQ:81739279 e-mail: project_maker@sina.com

 * 需要的基本知识 java.lang.String API

 * 本段程序的目的是找到我们要使用的数据在什么地方

 * 注意: NCDC的气温数据精确到小数点后1为

 */

public class MaxTemperatureReady {

 /** 在1901年数据中,复制出来第一行,用于寻找年份、气温 */

 private static final String data = "0029029070999991901010106004+64333+023450FM-12+000599999V0202701N015919999999N0000001N9-00781+99999102001ADDGF108991999999999999999999";

 

 public static void main(String[] args) {

  

  // 显示年份 运行结果 15 ,我们需要4为,至19

  System.out.println(data.indexOf("1901"));

  

  // 气温,是一个数字,有正数和负数, 在字符串中,找看看,+/-在哪里 , 以确定截取区域

  // 在这里我没发现 有 +64333+025450FM-12+000599999V020........N9-00781+

  // 结论, N0000001N9至+这个位置之间是气温, 找他的位置

  // 运行结果 77 加上这10位,结果为87 , 如果低87为是+不需要 下一个符号+ 之前是5为

  System.out.println(data.indexOf("N0000001N9"));

  

  // 找一条看看

  String fmt = "%s年%d度";

  // 注意:不含92 也就是 这里能娶到-0078 零下7.8的意思, 如果零下78.1冻死人诶~~~

  System.out.println(String.format(fmt, data.substring(15,19), Integer.parseInt(data.substring(87, 92)) ));

  // 好了, 数据如何提取我们已经知道了.

 }

}

开始编写程序来分析最高气温吧.

package org.pcwl;

import java.io.BufferedReader;

import java.io.DataOutputStream;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

/**

 *

 * @author E-mail:project_maker@sina.com

 * 计算最高气温, 本程序分2个部分, 一个部分读取数据,一个部分对数据进行计算,输出结果

 */

public class JavaMaxTemperature {

 

 /** 用于存储读取到的年份和气温数据

  *  一年中有很多天<valueList<Integer>>,

  *  年份是固定的几个<key>

  */

 private static Map<String, List<Integer>> temperatureMap= new HashMap<String, List<Integer>>();

 private static File outDirectory = null;

 private static DataOutputStream dos = null;

 /**

  * @throws IOException

  */

 public static void main(String[] args) throws IOException {

  if(args.length != 2){

   System.out.println("请输入数据来源和数据目标");

  }

  /* 创建目标文件*/

  outDirectory = new File(args[1]);

  File outFile = new File(outDirectory, "part-0000");

  dos = new DataOutputStream(new FileOutputStream(outFile));

  

  /* 读取指定文件夹下的文件 */

  File inDirectory = new File(args[0]);

  for(File inFile : inDirectory.listFiles()){

   readData(inFile);

  }

  

  /* 关闭输出流 */

  dos.close();

  

 }

 /**

  * 读取数据, 把年份作为map的Key, List<Integer>存放每一天的气温数据

  * @param file

  * @throws IOException

  */

 static void readData(File file) throws IOException {

  BufferedReader br = new BufferedReader(new FileReader(file));

  String line = null;

  while(null != (line=br.readLine())){

   String year = line.substring(15, 19);

   int temperature;

   if(line.charAt(87) == '+'){

    temperature = Integer.parseInt(line.substring(88, 92));

   }else{

    temperature = Integer.parseInt(line.substring(87, 92));

   }

   /* 运行程序发现1901结果为9999, 黄金都能融化,显然999是个错误的数据,排除 */

   if(temperature != 9999 ){

    addYearAndTemperature(year, temperature);

   }

  }

  

  out();

 }

 /**

  * 添加年份和气温数据到map中

  * @param year

  * @param temperature

  */

 static void addYearAndTemperature(String year, int temperature){

  List<Integer> list;

  if(temperatureMap.containsKey(year)){

   list = temperatureMap.get(year);

  }else{

   list = new ArrayList<Integer>();

  }

  list.add(temperature);

  temperatureMap.put(year, list);

  

 }

 /**

  * 计算最高气温并且输出

  * @throws IOException

  */

 static void out() throws IOException{

  int max = Integer.MIN_VALUE;

  String year = null;

  for(Iterator<String> it = temperatureMap.keySet().iterator(); it.hasNext();){

   year= it.next();

   List<Integer> temperatures = temperatureMap.get(year);

   for(Integer i : temperatures){

    max = Math.max(max, i);

   }

  }

  dos.writeUTF(year +"\t" + max+"\n");

  

  temperatureMap.clear();

 }

}

src为代码,data为数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: