public void testTextIndex(){
Text text=new Text("hadoop");
Assert.assertEquals(text.getLength(), 6);
Assert.assertEquals(text.getBytes().length, 6);
Assert.assertEquals(text.charAt(2),(int)‘d‘);
Assert.assertEquals("Out of bounds",text.charAt(100),-1);
}
public void testTextFind() {
Text text = new Text("hadoop");
Assert.assertEquals("find a substring",text.find("do"),2);
Assert.assertEquals("Find first ‘o‘",text.find("o"),3);
Assert.assertEquals("Find ‘o‘ from position 4 or later",text.find("o",4),4);
Assert.assertEquals("No match",text.find("pig"),-1);
}
当uft-8编码后的字节大于两个时,Text和String的区别就会更清晰,因为String是按照unicode的char计算,而Text是按照字节计算。我们来看下1到4个字节的不同的unicode字符
4个unicode分别占用1到4个字节,u+10400在java的unicode字符重占用两个char,前三个字符分别占用1个char.
import java.io.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.util.StringUtils;
import junit.framework.Assert;
public class textandstring {
public static void string() throws UnsupportedEncodingException {
String str = "\u0041\u00DF\u6771\uD801\uDC00";
Assert.assertEquals(str.length(), 5);
Assert.assertEquals(str.getBytes("UTF-8").length, 10);
Assert.assertEquals(str.indexOf("\u0041"), 0);
Assert.assertEquals(str.indexOf("\u00DF"), 1);
Assert.assertEquals(str.indexOf("\u6771"), 2);
Assert.assertEquals(str.indexOf("\uD801\uDC00"), 3);
Assert.assertEquals(str.charAt(0), ‘\u0041‘);
Assert.assertEquals(str.charAt(1), ‘\u00DF‘);
Assert.assertEquals(str.charAt(2), ‘\u6771‘);
Assert.assertEquals(str.charAt(3), ‘\uD801‘);
Assert.assertEquals(str.charAt(4), ‘\uDC00‘);
Assert.assertEquals(str.codePointAt(0), 0x0041);
Assert.assertEquals(str.codePointAt(1), 0x00DF);
Assert.assertEquals(str.codePointAt(2), 0x6771);
Assert.assertEquals(str.codePointAt(3), 0x10400);
}
public static void text() {
Text text = new Text("\u0041\u00DF\u6771\uD801\uDC00");
Assert.assertEquals(text.getLength(), 10);
Assert.assertEquals(text.find("\u0041"), 0);
Assert.assertEquals(text.find("\u00DF"), 1);
Assert.assertEquals(text.find("\u6771"), 3);
Assert.assertEquals(text.find("\uD801\uDC00"), 6);
Assert.assertEquals(text.charAt(0), 0x0041);
Assert.assertEquals(text.charAt(1), 0x00DF);
Assert.assertEquals(text.charAt(3), 0x6771);
Assert.assertEquals(text.charAt(6), 0x10400);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
text();
try {
string();
} catch(UnsupportedEncodingException ex) {
}
}
}
在Text中对unicode字符的迭代是相当复杂的,因为与unicode所占的字节数有关,不能简单的使用index的增长来确定。首先要把Text对象转换为java.nio.ByteBuffer对象,然后再利用缓冲区对Text对象反复调用bytesToCodePoint方法,该方法能获取下一代码的位置,并返回相应的int值,最后更新缓冲区中的位置。通过bytesToCodePoint()方法可以检测出字符串的末尾,并返回-1值。看一下示例代码:
import java.io.*;
import java.nio.ByteBuffer;
import org.apache.hadoop.io.*;
import org.apache.hadoop.util.StringUtils;
import junit.framework.Assert;
public class textandstring {
public static void main(String[] args) {
// TODO Auto-generated method stub
Text t = new Text("\u0041\u00DF\u6771\uD801\uDC00");
ByteBuffer buf = ByteBuffer.wrap(t.getBytes(), 0, t.getLength());
int cp;
while(buf.hasRemaining() && (cp = Text.bytesToCodePoint(buf)) != -1) {
System.out.println(Integer.toHexString(cp));
}
}
}