hadoop源码分析之mapredue的泛型类解析

首先,我们来看看下面函数
public static class TokenizerMapper 
    extends Mapper <Object, Text, Text, IntWritable> {

private final static IntWritable one = new IntWritable(1);
private Text word = new Text();

public void map( Object key, Text value, Context context
                 ) throws IOException, InterruptedException {
   StringTokenizer itr = new StringTokenizer(value.toString());
   while (itr.hasMoreTokens()) {
     word.set(itr.nextToken());
     context.write(word, one);
   }
}
}

我们平常在写mapreduce的过程中,似乎看到了 <Object, Text, Text, IntWritable>   这几个参数,那么几个参数是什么意思?带有<>尖括号,又是什么意思。这个我们是否想过。
我们平常在类中,是很少带有参数的,即使带有参数,也是这种类型,比如
public void map(Object key, Text value, Context context  ) 

这个是很容易理解。key是object类型,value是Text类型。


什么是泛型


public static class TokenizerMapper   extends Mapper <Object, Text, Text, IntWritable>  那么这个的含义是什么?


如果我们知道泛型类,我们就知道带有尖括号代表泛型。比如:


[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
 
  * 自定义泛型
 
  * @author tfq
 
  *
 
  */
 
public class GenericArrayList<E> {
 
  
 
   Object[] objects= new Object[ 10 ];
 
   int index= 0 ;
 
 
   /**
 
   * 父类引用指向子类对象
 
   * @param o
 
   */
 
   public void add(E o){
 
    if (index==objects.length){
 
       Object[] newObjects= new Object[objects.length* 2 ];
 
       System.arraycopy(objects, 0 , newObjects, 0 , objects.length);
 
       objects=newObjects;
 
     }
 
      objects[index]=o;
 
      index++;
 
   }
 
 
     /**
 
     * 获取数组的长度
 
     * @return
 
     */
 
     public int size(){
 
        return index;
 
     }
 
 
    public static void main(String[] args) {
 
        //把E替换成你想要实现的类或类型
 
         GenericArrayList<String> geneArray= new GenericArrayList<String>();
 
         geneArray.add( "a" );
 
         System.out.println(geneArray.size());
 
     }
 
 
}



好吧,上面有些复杂,这里把它们抽离出来:

public class GenericArrayList< E >{}

public static void main(String[] args) {

//把E替换成你想要实现的类或类型

GenericArrayList<String> geneArray=new GenericArrayList< String >();

}

public class GenericArrayList< E >在实例化的时候,被替换为了 String

那么我们还可以怎么做
GenericArrayList<String> geneArray=new GenericArrayList< Integer   >();

从这里我们是否能够明白泛型的方便了。
对于一个类型
当我们不确定是使用整型或则字符串类型的时候,我们可以使用泛型
当我们有时候使用泛型,有时候使用整型,我们可以使用泛型。
泛型是什么?
泛型是对数据类型的抽象。
那么什么是数据类型
Integer,String,shot等这些都是数据类型。


什么是泛型接口/类

这样我们明白了泛型,可是
<Object, Text, Text, IntWritable>  
这个仍然无法解释,因为这里没有实例化,而且带有尖括号。那么它是什么意思。
下面我们给出一个小例子


[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//泛型接口定义
interface ISum<T> {
     public abstract void sum(T... t);
}
 
//从泛型接口继承的具体类型类
class IntSum implements ISum<Integer> {
     public void sum(Integer... t) {
         int s = 0 ;
         for ( int e : t) {
             s += e;
         }
         System.out.println(s);
     }
}
 
class DoubleSum implements ISum<Double> {
     public void sum(Double... t) {
         double s = 0.0 ;
         for ( double e : t) {
             s += e;
         }
         System.out.println(s);
     }
}
 
//使用示例
public class SumMain {
 
     public static void main(String[] args) {
 
         IntSum intSum = new IntSum();
         intSum.sum( 1 , 2 , 3 , 4 , 5 );
         intSum.sum( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 );
 
         DoubleSum doubleSum = new DoubleSum();
         doubleSum.sum( 1.0 , 1.5 , 2.0 , 2.5 , 3.0 );
         doubleSum.sum( 1.0 , 1.5 , 2.0 , 2.5 , 3.0 , 3.5 , 4.0 , 4.5 , 5.0 );
 
     }
}



interface ISum< T > {
}

//从泛型接口继承的具体类型类
class IntSum implements ISum< Integer >

我们看到上面是一个接口 ISum 和继续这个接口的类 IntSum

如果足够细心你会发现interface ISum< T > 中T被置换为 Integer  所以从这里,我们得出
当一个泛型接口,被类继承的时候,泛型会被具体化。


好的,这样我们就明白了


mapreduce中Mapper泛型类

public static class TokenizerMapper 
    extends Mapper <Object, Text, Text, IntWritable> {

private final static IntWritable one = new IntWritable(1);
private Text word = new Text();

public void map( Object key, Text value, Context context
                 ) throws IOException, InterruptedException {
   StringTokenizer itr = new StringTokenizer(value.toString());
   while (itr.hasMoreTokens()) {
     word.set(itr.nextToken());
     context.write(word, one);
   }
}
}

我们看到TokenizerMapper继承Mapper,类型被具体化了,也即是说Mapper可能是一个泛型类,好的,这时候我们在看源码
public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>

 

果然Mapper是一个泛型类。




那么这时候,我们在回头看TokenizerMapper类。
public static class TokenizerMapper 
    extends Mapper <Object, Text, Text, IntWritable>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值