• java 遍历String


    Java字符串是一系列的Unicode字符序列,但是,它却常常被误认为是char序列。于是,我们经常这样来遍历字符串:

    package testchar;
    
    public class TestChar2 {
    	public static void main(String[] args) {
    		String s = "u0041u00DFu6771ud801uDC00";
    		for(int i = 0; i < s.length(); i++) {
    			System.out.println(s.charAt(i));
    		}
    	}
    }

    然后,得到了意料之外的结果:

    A

    ß

    ?

    ?

    之所以会这样,是因为Unicode字符和Java的char类型不能等同起来。实际上,Java中的char类型能表示的字符只是Unicode字符的子集,因为char只有16位,也就是说,它只能表示65536(2的16次方)个字符,但实际的Unicode字符数超过这个数字。在Java中,用UTF-16编码char和String中的字符,一个字符对应的编码值被称为一个代码点。有的代码点用16位编码,被称为一个代码单元,像char表示的那些字符;有的代码点用32位编码,也就是用两个连续的代码单元编码,如上文中的ud801uDC00。其实,我们遍历一个字符串,遍历的是这个字符串中所有代码点,而

    s.length()

    返回的是字符串s中代码单元的个数。当i对应的代码单元只是一个32位代码点的一部分时,

    s.charAt(i)

    也就不能像我们希望的那样工作了。

    下面给出了几种正确遍历一个字符串的方法:

    package testchar;
    
    /**
     * 正确遍历String
     * 
     * @author yuncong
     * 
     */
    public class TestChar {
    
    	public static void main(String[] args) {
    		String s = "u0041u00DFu6771ud801uDC00";
    		// 获得字符串中代码点的数量
    		int cpCount = s.codePointCount(0, s.length());
    		for (int i = 0; i < cpCount; i++) {
    			int index = s.offsetByCodePoints(0, i);
    			int cp = s.codePointAt(index);
    			if (!Character.isSupplementaryCodePoint(cp)) {
    				System.out.println((char) cp);
    			} else {
    				System.out.println(cp);
    			}
    		}
    
    		System.out.println("-------------------");
    
    		for (int i = 0; i < s.length(); i++) {
    			int cp = s.codePointAt(i);
    			if (!Character.isSupplementaryCodePoint(cp)) {
    				System.out.println((char) cp);
    			} else {
    				System.out.println(cp);
    				i++;
    			}
    		}
    		
    		System.out.println("-------------------");
    		
    		// 逆向遍历字符串
    		for(int i = s.length() - 1; i >= 0; i--) {
    			int cp = 0;
    			// 当i等于0的时候,只剩下一个代码单元,不可能是辅助字符
    			if (i == 0) {
    				cp = s.codePointAt(0);
    				System.out.println((char)cp);
    			} else {
    				// 只有在i大于0的时候才可以退,并且
    				// 因为剩下的代码单元大于2,所以接下
    				// 来访问的两个代码单元可能表示辅助
    				// 字符;
    				// 退一个代码单元
    				i--;
    				cp = s.codePointAt(i);
    				if (Character.isSupplementaryCodePoint(cp)) {
    					System.out.println(cp);
    				} else {
    					// 如果cp不是辅助字符,就回到遍历的正常位置
    					i++;
    					cp = s.codePointAt(i);
    					System.out.println((char)cp);
    				}
    			}
    		}
    		
    	}
    
    }

    (天坑啊,博客中不能出现Java中的辅助字符)

  • 相关阅读:
    P4868 天天和不可描述
    天天寄快递
    iOS开发资源网站
    找图标的网址
    json解析网址
    屏幕适配
    加密 解密
    json解析网址
    IOS设计模式之三:MVC模式
    什么是Cocoa?什么是Xcode?什么是Framework?
  • 原文地址:https://www.cnblogs.com/yelongsan/p/6429864.html
Copyright © 2020-2023  润新知