Java 减速器回路异常行为

Java 减速器回路异常行为,java,hadoop,mapreduce,reduce,Java,Hadoop,Mapreduce,Reduce,我是mapreduce的新手,我正在尝试从两个不同的csv文件连接两种不同类型的行 地图是好的,我加载两个文件A和B,我用相同的键匹配我想要的行 在减速机里,我有一种非常奇怪的行为,我无法理解。从A开始的行以incident.开头,从B开始的行以meteo.开头。我想确定一行是来自a还是B,然后获取该行的其余部分,但是当我测试此代码时 for(Text val : values){ StringTokenizer line = new StringToke

我是mapreduce的新手,我正在尝试从两个不同的csv文件连接两种不同类型的行

地图是好的,我加载两个文件A和B,我用相同的键匹配我想要的行

在减速机里,我有一种非常奇怪的行为,我无法理解。从A开始的行以
incident.
开头,从B开始的行以
meteo.
开头。我想确定一行是来自a还是B,然后获取该行的其余部分,但是当我测试此代码时

        for(Text val : values){
            StringTokenizer line = new StringTokenizer(val.toString(), "#");
            String comparable = line.nextToken();
            context.write(key,new Text(comparable));
        } 
我收到以下输出,这是正常的

2015-12-31;X    meteo
2015-12-31;X    accident
2015-12-31;X    accident
2015-12-31;X    accident
2015-12-31;X    accident
然后我做这个

        for(Text val : values){
            StringTokenizer line = new StringTokenizer(val.toString(), "#");
            String comparable = line.nextToken();
            if (comparable.equals("meteo"))
                comparable = line.nextToken();
            context.write(key,new Text(comparable));
        }
2015-12-31;X    ;17.8;14:00;9.1;04:40;25;12:20;19;19:00;0;0;0
2015-12-31;X    accident
2015-12-31;X    accident
2015-12-31;X    accident
2015-12-31;X    accident
这也可以。 然后我执行以下操作来存储meteo

        String meteo;
        for(Text val : values){
            meteo = "hi";
            StringTokenizer line = new StringTokenizer(val.toString(), "#");
            String comparable = line.nextToken();
            if (comparable.equals("meteo"))
                meteo = line.nextToken();
            context.write(key,new Text(meteo));
        } 
2015-12-31;X    hi
2015-12-31;X    hi
2015-12-31;X    hi
2015-12-31;X    hi
2015-12-31;X    hi
预期的结果是什么时候

2015-12-31;X    ;17.8;14:00;9.1;04:40;25;12:20;19;19:00;0;0;0
2015-12-31;X    hi
2015-12-31;X    hi
2015-12-31;X    hi
2015-12-31;X    hi
这是对我的问题的简化,但它显示了一种非常奇怪的行为。实际上,我想要的是用相同的键将meteo线附加到每个事故线,这是我的最终目标,但如果这不起作用。。。我不知道如何才能做到这一点(我的想法是获取meteo行,存储它,然后将其附加到每个意外行)

编辑

接下来,我将添加映射器的代码和确切的输入,以澄清问题

 public void map(Object key, Text value, Context context
                 ) throws IOException, InterruptedException { 

   StringTokenizer lines = new StringTokenizer(value.toString(), "\n");
   while (lines.hasMoreTokens()){
        StringTokenizer line = new StringTokenizer(lines.nextToken(),";");
        String csvLine = new String(); //this will be the output value
        String atr = line.next.Token(); //with the first atribute i will diferenciate between meteo and accidents
        boolean isMeteo = false;
        if(atr.equals("0201X")) isMeteo=true; 
        if(!isMeteo){  //if is a accident line, I search the atributs to put the date in the key (i==6,7,8)
                  int i=1;
                  csvLine=atr;
                  while(line.hasMoreTokens()){
                      String aux= line.nextToken();
                      csvLine+=";"+aux;
                      if(i==6) id =aux;
                      else if(i==7 || i==8){
                          int x = Integer.parseInt(aux);
                          if(x<10)aux = "0"+aux;
                          id+="-"+aux;
                      }
                      else if(i==13){ //this is the X in the key, that is for identify the meteo station (this is not important in my problem)
                          aux = aux.substring(0,aux.length()-1);
                          id+=";"+aux;
                          csvLine= csvLine.substring(0,csvLine.length()-1);
                      }
                      ++i;
                  }
        }
        else if(isMeteo){
            id = line.nextToken(); //in the second column we have the complete date string
            id+=";X";  //this file has the data of the meteo station X
            csvLine+=";"+toCsvLine(line);
        }
        Text outKey = new Text(id);
        Text ouyKey = new Text(csvLine);
        context.write(outKey,outValue);
 }

 public String toCsvLine(StringTokenizer st){
     String x = new String();
     x = st.nextToken();
     while(st.hasMoreTokens()){
         x+=";"+st.nextToken();
     }
     return x;
 }      
意外事故.csv:

 2015S009983;Ciutat Vella;la Barceloneta;Mar;Dc;Laboral;2015;12;30;22;Altres;4581220,92;432258,31;X 
 2015S009984;Sant Mart�;Sant Mart� de Proven�als;Cant�bria;Dc;Laboral;2015;12;30;20;Col.lisi� fronto-lateral;4585862,62;433330,95;X 
 2015S009985;Eixample;la Nova Esquerra de l'Eixample;Cal�bria;Dj;Laboral;2015;12;31;00;Caiguda (dues rodes);4582094,15;428800,57;X  
 2015S009987;Eixample;la Dreta de l'Eixample;Gr�cia;Dj;Laboral;2015;12;31;02;Col.lisi� lateral;4582944,96;430133,41;X   
 2015S009988;Eixample;la Nova Esquerra de l'Eixample;Arag�;Dj;Laboral;2015;12;31;07;Abast;4581873,45;429312,63;X    
 2015S009989;Ciutat Vella;la Barceloneta;Mar�tim de la Barceloneta;Dj;Laboral;2015;12;31;08;Abast;4581518,06;432606,87;X    

你能把
字符串
包括在内吗。如果找到一个等于
meteo
的令牌,那么应该包含下一个令牌,这是正确的行为吗?我想要的是,当字符串compariable为“meteo”时,保存下一个令牌的值。我想保存下一个令牌,因为我将在此之后使用它。我运行了您的代码并获得了预期的结果。我不得不猜测输入是什么样子的,这是这里缺少的主要信息。也许可以添加与预期输出相对应的输入文本。除此之外,您的代码看起来是正确的。我刚刚添加了映射器函数和输入行。
 2015S009983;Ciutat Vella;la Barceloneta;Mar;Dc;Laboral;2015;12;30;22;Altres;4581220,92;432258,31;X 
 2015S009984;Sant Mart�;Sant Mart� de Proven�als;Cant�bria;Dc;Laboral;2015;12;30;20;Col.lisi� fronto-lateral;4585862,62;433330,95;X 
 2015S009985;Eixample;la Nova Esquerra de l'Eixample;Cal�bria;Dj;Laboral;2015;12;31;00;Caiguda (dues rodes);4582094,15;428800,57;X  
 2015S009987;Eixample;la Dreta de l'Eixample;Gr�cia;Dj;Laboral;2015;12;31;02;Col.lisi� lateral;4582944,96;430133,41;X   
 2015S009988;Eixample;la Nova Esquerra de l'Eixample;Arag�;Dj;Laboral;2015;12;31;07;Abast;4581873,45;429312,63;X    
 2015S009989;Ciutat Vella;la Barceloneta;Mar�tim de la Barceloneta;Dj;Laboral;2015;12;31;08;Abast;4581518,06;432606,87;X