Hadoop中Text类型 与 String的区别

Hadoop中Text类型 与 String的区别

在区别Hadoop中Text类型 与 String时,如果使用单字节来编码的字符时,很难看它们的区别,但是使用多字节进行编码时就可以看出其中的区别。
一,Unicode
Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。
Unicode可以想象成一种映射关系,将世界上的字符都映射成U+数字,它不涉及编码,仅仅是一种映射关系。所有Unicode字符(除了U+10400)在Java中都可以使用以”\u”开头的单个java char来表示。称为“字符代理对”。
Unicode的编码方案是被UTF(Unicode Transformation Formats)定义的。常见的是UTF-8,UTF-16。
1. UTF-8:是一种变长的编码方案,在0~127之间的Unicode码将会使用一个字节来编码(并且这个映射和ASCⅡ相同),超过127的用2个或4个字节;
2. UTF-16:固定使用2个或4个字节。
Unicode只是一个用来映射字符和数字的标准,它的编码方式有UTF定义、

二,Text类型
Text是正对UTF-8序列的Writable类。一般可以认为是对String的Writable。Text替代了UTF8类。但是Text不支持对字节数超过32767的字符串进行编码。并且它使用的是Java的UTF-8修订版。
Text类使用整型来存储字符串编码中所需的字节数。即Text存储的是字节数,并且这个字节数用整型存储。除此之外,Text使用标准的UTF-8编码。

三,区别
1,Text和String的区别可以从leght、indexOf()、charAt()看出,Text的位置是UTF-8编码后的字节偏移量,长度是UTF-8编码后的字节数组大小,而String针对的是Java char.

package Hadoop.writable;

import java.io.UnsupportedEncodingException;

import org.apache.hadoop.io.Text;
import org.junit.Test;

public class StringComparisonTest {
    @Test
    public void string () throws UnsupportedEncodingException{
        String s= "big";
        System.out.println("String:"+s);
        System.out.println(s.length());
        System.out.println(s.getBytes("UTF-8").length);
        System.out.println(s.indexOf("b"));
        System.out.println(s.indexOf("i"));
        System.out.println(s.indexOf("g"));
        System.out.println(s.charAt(0));
        System.out.println(s.charAt(1));
        System.out.println(s.charAt(2));
    }
    @Test
    public void text(){
        Text t=new Text("big");
        System.out.println("Text:"+t);
        System.out.println(t.getLength());
        System.out.println(t.find("b"));
        System.out.println(t.find("i"));
        System.out.println(t.find("g"));
        System.out.println(t.charAt(0));
        System.out.println((int)'b');
    }
}

运行结果
String:big
3 //s.length()
3 //s.getBytes(“UTF-8”).length
0
1 //s.indexOf(“i”)
2
b //s.charAt(0)
i
g
Text:big
3 //t.getLength()
0
1 //t.find(“i”)
2
98 //t.charAt(0)
98 //(int)’b’
因为测试的字符串是”big”,编码后是单字节的,所以s.getBytes(“UTF-8”).length,采用 UTF-8编码后的长度与s.length()的长度相同都是3,而t.getLength()采用UTF-8编码后的长度也是3。
由于UTF-8编码后的字节偏移量都是1,所以s.indexOf(“i”)和t.find(“i”)的结果都是相同的。
但是在charAt()就不同,Text的charAt返回一个该编码位置的int类型值。而String返回该位置的char类型值。

下面换成多字节编码的例子

package Hadoop.writable;

import java.io.UnsupportedEncodingException;

import org.apache.hadoop.io.Text;
import org.junit.Test;

public class StringComparisonTest {
    @Test
    public void string () throws UnsupportedEncodingException{
        String s= "\u0045\u00fd\u00DF";
        System.out.println("String:"+s);
        System.out.println(s.length());
        System.out.println(s.getBytes("UTF-8").length);
        System.out.println(s.indexOf("\u0045"));
        System.out.println(s.indexOf("\u00fd"));
        System.out.println(s.indexOf("\u00DF"));
        System.out.println(s.charAt(0));
        System.out.println(s.charAt(1));
        System.out.println(s.charAt(2));
    }
    @Test
    public void text(){
        Text t=new Text("\u0045\u00fd\u00DF");
        System.out.println("Text:"+t);
        System.out.println(t.getLength());
        System.out.println(t.find("\u0045"));
        System.out.println(t.find("\u00fd"));
        System.out.println(t.find("\u00DF"));
        System.out.println(t.charAt(0));
        System.out.println((int)'\u0045');
    }
}

运行结果
String:Eýß
3 //s.length()
5 //s.getBytes(“UTF-8”).length
0 //s.indexOf(“\u0045”)
1
2
E
ý
ß
Text:Eýß
5 //t.getLength()
0 //t.find(“\u0045”)
1
3
69
69
这个测试证实String的长度是其包含char编码单元的个数(3,三个字符构成),但Text对象的长度却是其UTF-8编码的字节数(5=1+2+2)。同样的,String类的indexOf()
方法返回char编码单元的索引位置,而Text类的find()方法则返回字节偏移量。

2,与String的另一个区别是Text是可变的。通过调用set()方法,至于String为什么不可变,可以看博文http://blog.csdn.net/yangjjuan/article/details/72811513

Text t= new Text("hadoop");
t.set("hbase");

3,Text转换为String对象,这样就可以用String的API操作

        Text t= new Text("hadoop");
        t.set("hbase");
        t.toString();

你可能感兴趣的:(Hadoop,HADOOP学习之路)