【问题标题】:Hadoop mapreduce custom writable static contextHadoop mapreduce 自定义可写静态上下文
【发布时间】:2016-04-13 06:17:42
【问题描述】:

我正在做大学作业,我们必须使用 hadoop mapreduce。我正在尝试创建一个新的自定义可写对象,因为我想将键值对输出为 (key, (doc_name, 1))。

public class Detector {

    private static final Path TEMP_PATH = new Path("temp");
    private static final String LENGTH = "gramLength";
    private static final String THRESHOLD = "threshold";


    public class Custom implements Writable {

        private Text document;
        private IntWritable count;

        public Custom(){
            setDocument("");
            setCount(0);
        }

        public Custom(String document, int count) {
            setDocument(document);
            setCount(count);
        }

        @Override
        public void readFields(DataInput in) throws IOException {
            // TODO Auto-generated method stub
            document.readFields(in);
            count.readFields(in);
        }

        @Override
        public void write(DataOutput out) throws IOException {
            document.write(out);
            count.write(out);
        }

        public int getCount() {
            return count.get();
        }

        public void setCount(int count) {
            this.count = new IntWritable(count);
        }

        public String getDocument() {
            return document.toString();
        }

        public void setDocument(String document) {
            this.document = new Text(document);
        }

    }

    public static class NGramMapper extends Mapper<Text, Text, Text, Text> {
        private int gramLength;
        private Pattern space_pattern=Pattern.compile("[ ]");
        private StringBuilder gramBuilder= new StringBuilder();

        @Override
        protected void setup(Context context) throws IOException,      InterruptedException{
            gramLength=context.getConfiguration().getInt(LENGTH, 0);
        }

        public void map(Text key, Text value, Context context) throws IOException, InterruptedException {
            String[] tokens=space_pattern.split(value.toString());
            for(int i=0;i<tokens.length;i++){
                gramBuilder.setLength(0);
                if(i+gramLength<=tokens.length){
                    for(int j=i;j<i+gramLength;j++){
                        gramBuilder.append(tokens[j]);
                        gramBuilder.append(" ");
                    }
                    context.write(new Text(gramBuilder.toString()), key);
                }
            }
        }
    }


    public static class OutputReducer extends Reducer<Text, Text, Text, Custom> {

        public void reduce(Text key, Iterable<Text> values, Context context)
                throws IOException, InterruptedException {
            for (Text val : values) {
                context.write(key,new Custom(val.toString(),1));
            }
        }
    }

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

        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(conf);
        conf.setInt(LENGTH, Integer.parseInt(args[0]));
        conf.setInt(THRESHOLD, Integer.parseInt(args[1]));

        // Setup first MapReduce phase
        Job job1 = Job.getInstance(conf, "WordOrder-first");
        job1.setJarByClass(Detector.class);
        job1.setMapperClass(NGramMapper.class);
        job1.setReducerClass(OutputReducer.class);
        job1.setMapOutputKeyClass(Text.class);
        job1.setMapOutputValueClass(Text.class);
        job1.setOutputKeyClass(Text.class);
        job1.setOutputValueClass(Custom.class);
        job1.setInputFormatClass(WholeFileInputFormat.class);
        FileInputFormat.addInputPath(job1, new Path(args[2]));
        FileOutputFormat.setOutputPath(job1, new Path(args[3]));

        boolean status1 = job1.waitForCompletion(true);
        if (!status1) {
            System.exit(1);
        }
    }
}

当我将代码编译到类文件时,我得到了这个错误:

Detector.java:147: error: non-static variable this cannot be referenced from a static context
context.write(key,new Custom(val.toString(),1));

我遵循了关于自定义可写的不同教程,我的解决方案与其他解决方案相同。有什么建议吗?

【问题讨论】:

  • 编写自定义可写文件是多余的。尝试使用 Avro:avro.apache.org

标签: java hadoop mapreduce writable


【解决方案1】:

静态字段和方法与所有实例共享。它们用于特定于类而不是特定实例的值。尽可能远离他们。

要解决您的问题,您需要实例化您的类的一个实例(创建一个对象),以便运行时可以为该实例保留内存;或将您正在访问的部分更改为具有static 访问权限(不推荐!)。

关键字this 用于引用确实是实例的东西(因此是this 东西),而不是static,在这种情况下应该由类名引用。您在不允许的 static 上下文中使用它。

【讨论】:

  • 感谢您的回答。你的意思是哪个类我需要创建一个实例?我正在通过“context.write(key,new Custom(val.toString(),1));”在 Reducer 中创建一个 Custom 实例
  • 这绝对是错误的。 Custom 类需要定义为静态类,否则如果不先实例化 Detector,就无法创建它的实例。不涉及字段访问。
  • @ThomasJungblut 我用“一般术语”回答,因此是第二段和第三段。 this 没有明确使用,但是在创建 Custom 的新实例时,它不是您指出的 static,并被所有其他 static 类使用
猜你喜欢
  • 2023-03-13
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-21
  • 1970-01-01
  • 2022-10-19
相关资源
最近更新 更多