0

嗨,我目前面临 Java 泛型问题:我需要使用的方法具有此签名

static<K1,V1,K2,V2> void addMapper(JobConf job, 
           Class<? extends Mapper<K1,V1,K2,V2>> klass, 
           Class<? extends K1> inputKeyClass, 
           Class<? extends V1> inputValueClass, 
           Class<? extends K2> outputKeyClass, 
           Class<? extends V2> outputValueClass, 
           boolean byValue, JobConf mapperConf) 

这就是我所说的

ChainMapper.addMapper(conf, NameMapper.class, 
           Object.class, Object.class, Object.class, Object.class, 
           false, nameYearConf);

其中 NameMapper 定义如下

public class NameMapper extends Mapper<Object, Object, Object, Object> { }

并且其他两个参数也正确初始化

JobConf conf = new JobConf(); JobConf nameYearConf = new JobConf(false);

当我尝试编译时,我收到以下错误

    src\MeanYear.java:107: error: method addMapper in class ChainMapper cannot be applied to given types;
                    ChainMapper.addMapper(conf, NameMapper.class, Object.class,
                               ^
      required: JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf
      found: JobConf,Class<MeanYear.NameMapper>,Class<Object>,Class<Object>,Class<Object>,Class<Object>,boolean,JobConf
      reason: no instance(s) of type variable(s) K1,V1,K2,V2 exist so that argument type Class<MeanYear.NameMapper> conforms to formal parameter type Class<? extends Mapper<K1,V1,K2,V2>>
      where K1,V1,K2,V2 are type-variables:
        K1 extends Object declared in method <K1,V1,K2,V2>addMapper(JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf)
        V1 extends Object declared in method <K1,V1,K2,V2>addMapper(JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf)
        K2 extends Object declared in method <K1,V1,K2,V2>addMapper(JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf)
        V2 extends Object declared in method <K1,V1,K2,V2>addMapper(JobConf,Class<? extends Mapper<K1,V1,K2,V2>>,Class<? extends K1>,Class<? extends V1>,Class<? extends K2>,Class<? extends V2>,boolean,JobConf)

我真的无法理解我做错了什么,我尝试了一些类似的示例并且编译并且它们有效。我也尝试了这里提供的一些示例,但没有成功。谢谢。

4

1 回答 1

1

乍一看,我的猜测是您正在混合新旧 api 包中的类:

ChainMapper(从 1.1.2 开始)仅针对旧 API 包实现(org.apache.hadoop.mapred),尚未移植到新 API 包(org.apache.hadoop.mapreduce)。

因此,ChainMapper.addMapper( Class<? extends Mapper<K1,V1,K2,V2>> klass) 的第二个参数应该是 type org.apache.hadoop.mapred.Mapper

由于您当前的映射器NameMapper扩展了 Mapper 类,这让我相信这是新的 api Mapper 类(org.apache.hadoop.mapreduce),因为新的 API 是一个类,而不是一个接口

您应该能够通过修改您的NameMapper类的签名以匹配旧 API Mapper 接口的签名来修复:

public class NameMapper extends MapReduceBase 
                        implements Mapper<Object, Object, Object, Object> { }

这也意味着您当前的地图方法的签名将需要从

protected void map(Object key, Object value, Context context) { }
// to
public void map(Object key, Object value, OutputCollector collector,
                Reporter reporter) { }

如果你正在使用新 Mapper API 的设置和清理方法,你也需要替换它们:

public void close() { } // instead of cleanup(Context) {}
public void configure(JobConf conf) { } // instead of setup(Context) {}
于 2013-06-25T10:13:04.663 回答