Hadoop: Text类和String类的比较
一般认为Text类和String类是等价的,但二者之间其实存在着不小差别:
以《Hadoop权威指南》中的案例为例,给定字符串 String s = "\u0041\u00DF\u6771\uD801\uDC00"; //s打印出来为"Aß東𐐀" ,字符串s由四个字符的Unicode编码组成:
| Unicode编码 | utf-8编码 | utf-8编码所占字节数 | |
| A | \u0041 | 0010 1001 (41) | 1Byte |
| ß | \u00DF | 1101 1101 (223) | 2Byte |
| 東 | \u6771 | 110 0111 0111 0001 (26481) | 3Byte |
| 𐐀 | \uD801\uDC00 | 1 0000 0100 0000 0000 (66560) | 4Byte |
对比一: Text对象的charAt( )方法返回的是当前位置字符对应的Unicode编码的位置(int类型),String对象返回的是当前位置对应的字符(char类型);
对比二: Text对象的长度是每个字符UTF-8编码所占字节数之和,String对象的长度对应char编码单元的个数;
对比三: Text对象的charAt( )方法与String对象的codePointAt( ) 方法更加类似,都返回当前位置字符对应的Unicode编码位置;
对比四: Text类的find( ) 方法返回的是当前位置的字节偏移量,String类的indexOf( )方法返回的是char编码单元中的索引位置。
具体对比可参考以下代码:
import org.apache.hadoop.io.Text;
import org.junit.Assert;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
public class StringTextComparisonTest {
@Test
public void string() throws UnsupportedEncodingException {
String s = "\u0041\u00DF\u6771\uD801\uDC00"; //"Aß東𐐀"
System.out.println(s.codePointAt(1));
// indexOf( )方法返回char编码单元的索引位置
Assert.assertEquals(s.indexOf("\u0041"), 0);
Assert.assertEquals(s.indexOf("\u00DF"), 1);
Assert.assertEquals(s.indexOf("\u6771"), 2);
Assert.assertEquals(s.indexOf("\uD801\uDC00"), 3);
// charAt( )方法返回当前位置对应的char类型字符
Assert.assertEquals(s.charAt(0),'\u0041');
Assert.assertEquals(s.charAt(1),'\u00DF');
Assert.assertEquals(s.charAt(2),'\u6771');
Assert.assertEquals(s.charAt(3),'\uD801');
Assert.assertEquals(s.charAt(4),'\uDC00');
// codePointAt( )方法返回当前位置对应的char类型字符在Uncoide编码中的位置
Assert.assertEquals(s.codePointAt(0),0x0041); // utf-8编码的位置,十六进制表示
Assert.assertEquals(s.codePointAt(1),0x00DF);
Assert.assertEquals(s.codePointAt(2),0x6771);
Assert.assertEquals(s.codePointAt(3),0x10400);
System.out.println(s.toString());
// test length
Assert.assertEquals(s.length(), 5);
Assert.assertEquals(s.getBytes().length, 10);
}
@Test
public void text(){
// 这个字符串按照UTF-8方案编码后所占的字节数是1+2+3+4(没有\uDC00是因为找不到)
Text t = new Text("\u0041\u00DF\u6771\uD801\uDC00");
System.out.println(t.charAt(1));
// find( )方法返回的是字符的字节偏移量
Assert.assertEquals(t.find("\u0041"), 0);
Assert.assertEquals(t.find("\u00DF"), 1);
Assert.assertEquals(t.find("\u6771"), 3);
Assert.assertEquals(t.find("\uD801\uDC00"), 6);
Assert.assertEquals(t.find("\uDC00"), -1);
// charAt( )方法返回对应的Unicode编码的位置
Assert.assertEquals(t.charAt(0),0x0041);
Assert.assertEquals(t.charAt(1),0x00DF);
Assert.assertEquals(t.charAt(3),0x006771);
Assert.assertEquals(t.charAt(6),0x10400);
System.out.println(t.toString());
Assert.assertEquals(t.getLength(), 10);
}
}
2018-01-03 10:40:28

浙公网安备 33010602011771号