• hadoop中Text类 与 java中String类的区别


    hadoop 中 的Text类与java中的String类感觉上用法是相似的,但两者在编码格式和访问方式上还是有些差别的,要说明这个问题,首先得了解几个概念;

    字符集: 是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。例如 unicode就是一个字符集,它的目标是涵盖世界上所有国家的文字和符号;

    字符编码:是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。即在符号集合与数字系统之间建立对应关系,它是信息处理的一项基本技术。通常人们用符号集合(一般情况下就是文字)来表达信息。而以计算机为基础的信息处理系统则是利用元件(硬件)不同状态的组合来存储和处理信息的。元件不同状态的组合能代表数字系统的数字,因此字符编码就是将符号转换为计算机可以接受的数字系统的数,称为数字代码。

    字符编码与字符集通常是一一对应的关系,例如utf-8,utf-16,utf-32都是unicode的不同编码格式;

    utf-8: 将unicode字符集分成1~4个字节的形式表示

    utf-16: 将unicode中编号从1到65536的字符都用两个字节表示(因为前65536个被认为是常用字符),大于65536的字符通过变换的方法变成4个字节来存储;

    utf-8 与 utf-16具体的编码变换方法,大家感兴趣的话可以从网上搜索来看;

    Hadoop中的Text类为了与外界更好的交互,采用的是utf-8的编码,而java的char,String,StringBuffer则默认使用的是utf-16编码;两者在使用和访问的时候其实是有一些差别的。
    这里借用了网上一篇博客中的例子 : http://blog.csdn.net/lastsweetop/article/details/9249411 来说明Text类与String类在访问上的区别


    第一个行表示unicode字符集中的序号(也是以16进制表示),第二行表示的是采用utf-8编码的情况,第三行表示的是用utf-16编码的情况,可以看到,第四个字符在utf-16编码下也占用4个字节(两个char单元,每个char单元是两字字节);

    代码如下,下面会分别解释结果中每一行的意思;

    String str = "u0041u00DFu6771uD801uDC00";

    Text text = new Text("u0041u00DFu6771uD801uDC00");

    System.out.println(str.length());
    System.out.println(str.getBytes("UTF-8").length);

    System.out.println(str.indexOf("u0041"));
    System.out.println(str.indexOf("u00DF"));
    System.out.println(str.indexOf("u6771"));
    System.out.println(str.indexOf("uD801uDC00"));

    System.out.println(str.charAt(0)=='u0041');
    System.out.println(str.charAt(1)=='u00DF');
    System.out.println(str.charAt(2)=='u6771');
    System.out.println(str.charAt(3)=='uD801');
    System.out.println(str.charAt(4)=='uDC00');

    System.out.println(str.codePointAt(0));
    System.out.println(str.codePointAt(1));
    System.out.println(str.codePointAt(2));
    System.out.println(str.codePointAt(3));


    System.out.println(text.getLength());
    System.out.println(text.find("u0041"));
    System.out.println(text.find("u00DF"));
    System.out.println(text.find("u6771"));
    System.out.println(text.find("uD801uDC00"));

    System.out.println(text.charAt(0));
    System.out.println(text.charAt(1));
    System.out.println(text.charAt(3));
    System.out.println(text.charAt(6));

    5 //String 中的getLength表示的是字符串中char单元的个数,如果String中包含4个字节(两个char单元)表示的字符,像上文中的第四个字符,getLength也是统计的是char     的数量,此时getLength的结果与实际的字符数是不同的。
    10 //getBytes() 方法返回根据相应编码(此例为utf-8)编码后的字节数;四个字符按utf-8编码后的字节数分别为1、2、3、4,所以总的字节数是10
    0 //String 的indexOf方法返回的字符出现的位置;
    1
    2
    3
    true  //String的charAt方法,返回的是相应位置的char编码单元
    true 
    true
    true
    true
    65  //String类的codePointAt()方法返回的是对应位置的unicode字符集序号,即上文u+0041的十进制表示;
    223 //
    26481
    66560 //这里要特别强调一下,由于第四个字符占据了两个char单元,codePointAt()方法会进行相应的判断,如果发现之后一位的char单元与当前位置的char单元是从属于一个              unicode字符的话,就将两者和在一起;如果不是的话,就单独输出当前的char单元;
    10 //Text 类的getLength方法返回的是utf-8编码之后的字节数
    0  //Text类的find方法也是按照字节数的偏移位置来的
    1
    3
    6
    65  //Text类的charAt方法也是返回对应的unicode字符集序号;
    223 
    26481
    66560 //如果这一句换成 charAt(5) 那么返回的是 -1

    由于Text的特点决定了:对Text的遍历会麻烦一些,需要变成bytes后通过bytesToCodePoint()方法进行访问;

    ByteBuffer buffer = ByteBuffer.wrap(text.getBytes(), 0, text.getLength());
    int cp;
    while (buffer.hasRemaining() && (cp = Text.bytesToCodePoint(buffer)) != -1) {
      System.out.println(Integer.toHexString(cp) + "haha");

    }

    输出结果为:

    41
    df
    6771
    10400

  • 相关阅读:
    教师不能太过于追求技巧
    两个有意思的数学谜题
    终于有博客啦
    215665645555
    Python 正则表达式之 sub 和 subn函数的使用
    python中可变数据类型和不可变数据类型
    python面试题手动总结答案锦集
    如何优雅的使用python中的代码注释
    使用win32com操作woord的方法记录
    redis问题:redis-server.exe双击闪退 win10系统
  • 原文地址:https://www.cnblogs.com/yuhan-TB/p/3752725.html
Copyright © 2020-2023  润新知