当前位置: 首页 > 知识库问答 >
问题:

为什么元组可写在传递给接收者时变为空

荣德厚
2023-03-14

我有一个映射(对象键、文本值、上下文上下文上下文),在上下文中使用Context.write()放置一个tupleWritable。在reduce(文本键、可迭代值、上下文上下文上下文)中,我读取了tupleWritable,但它是空的。下面是我的代码。这让我困惑,任何帮助都将不胜感激。

package boc.competition.team1;

import java.io.IOException;
import java.util.HashMap;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.join.TupleWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.MultipleInputs;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;;

public class App 
{
    public static class SCSTransMap extends Mapper<Object,Text,Text,TupleWritable>{
        private Text name = new Text();

        @Override
        public void map(Object key,Text value,Context context) throws IOException,InterruptedException{
                IntWritable i = new IntWritable(1);
                TupleWritable result = new TupleWritable(new IntWritable[] { i, new IntWritable(3)});
                System.out.println(result.get(0)+"====="+result.get(1));
//------here print the right value  1=====3
                context.write(name, result);
            }
        }
    }
    public static class reducer extends Reducer<Text,TupleWritable,Text,Text>{
        @Override
        public void reduce(Text key,Iterable<TupleWritable> values,Context context) throws IOException,InterruptedException{

            for(TupleWritable tuple:values) {
                System.out.println(tuple.get(0)+"====="+tuple.get(1));
// and here print 0=======0
            }

        }
    }

    public static void main( String[] args ) throws Exception
    {
        Configuration conf = new Configuration();

        Job job = Job.getInstance(conf,"team1Job");
        job.setJarByClass(App.class);
        job.setReducerClass(reducer.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(TupleWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        MultipleInputs.addInputPath(job, new Path("C:\\Program Files\\PuTTY\\data\\scs\\Scs_Journal.csv"), TextInputFormat.class,SCSTransMap.class);
        FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));

        System.exit(job.waitForCompletion(true)?0:1);
    }
}

共有2个答案

尉迟浩思
2023-03-14

根据元组可写.java源文件:

 * This is *not* a general-purpose tuple type. In almost all cases, users are
 * encouraged to implement their own serializable types, which can perform
 * better validation and provide more efficient encodings than this class is
 * capable. TupleWritable relies on the join framework for type safety and
 * assumes its instances will rarely be persisted, assumptions not only
 * incompatible with, but contrary to the general case.

也可以在这里看到克里斯·道格拉斯-3的回答:

您需要访问TupleWritable::setWritten(int)。如果您想在连接包之外使用
TupleWritable,那么您需要将此
(可能还有相关方法,如clearWritten(int))公开并重新编译。

可以肯定地说< code>TupleWritable并不是MapReduce作业的公共使用类。

公冶麒
2023-03-14

我使用用户定义可写类而不是tupleWritable类来将值从map传递给duce,这里是用户定义可写

package boc.competition.team1;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Writable;

public class IntPairWritable implements Writable {
        private IntWritable value1;
        private IntWritable value2;

        public IntPairWritable() {
            value1 = new IntWritable();
            value2 = new IntWritable();
        }

        public IntPairWritable(int value1, int value2) {
            this.value1 = new IntWritable(value1);
            this.value2 = new IntWritable(value2);
        }

        public int getInt1() {
            return value1.get();
        }

        public int getInt2() {
            return value2.get();
        }

        @Override
        public String toString() {
            return value1.toString()+" "+value2.toString();
        }

        @Override
        public void readFields(DataInput in) throws IOException {
            value1.readFields(in);
            value2.readFields(in);
        }

        @Override
        public void write(DataOutput out) throws IOException {
            value1.write(out);
            value2.write(out);
        }
}
 类似资料:
  • 问题内容: 为什么此代码无法编译? 为什么我不能将类变量传递给? 问题答案: 该操作符对引用类型,像,而不是对象,如。您可能想要类似 旁注:如果编写,您的代码将更加简洁 但是,我不确定是否需要某种方法。

  • 问题内容: 如果一个元组是不可变的,那么为什么它可以包含可变项呢? 似乎矛盾的是,当可变项(例如列表)确实被修改时,它所属的元组保持不变。 问题答案: 这是一个很好的问题。 关键的见解是,元组无法知道其中的对象是否可变。使对象可变的唯一方法是拥有一种更改其数据的方法。通常,无法检测到此情况。 另一个见解是Python的容器实际上不包含任何东西。相反,它们保留对其他对象的引用。同样,Python的变

  • 问题内容: 例如,如果我有一个变量,并且在主线程中声明了一个runnable,并且想将x传递给该runnable的方法,则必须对其进行声明。为什么? 问题答案: 因为如果能够更改它们,可能会导致很多问题,请考虑以下事项: 这是一个粗略的示例,但您可以看到可能发生许多无法解释的错误。这就是变量必须为最终变量的原因。这是解决上述问题的简单方法: 如果您需要更完整的说明,则有点像同步。Java希望防止您

  • 问题内容: 为什么经常被称为 代替 ? W3,MDN和MSDN都声明它是可选的。此外,ActiveX控件似乎不需要参数: 这种做法至少可以追溯到2005年的Google Maps中 ,但被缩小了,没有任何解释: 问题答案: 如果您看一下XMLHttpRequest的旧规范,似乎W3C似乎并不需要在某一点上将该参数设为可选,这可能导致人们提供了一个明确的null值,以防万一。 (搜索“应支持发送”)

  • 这里是Gradle 2.14和Groovy 2.4.7。我有以下groovy:

  • 我尝试过在活动之间传递对象,就像在Android上如何将对象从一个活动传递到另一个活动一样 Serializables类: