java 遍历String
Java字符串是一系列的Unicode字符序列,但是,它却常常被误认为是char序列。于是,我们经常这样来遍历字符串:
package testchar;
public class TestChar2 {
public static void main(String[] args) {
String s = "\u0041\u00DF\u6771\ud801\uDC00";
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位编码,也就是用两个连续的代码单元编码,如上文中的\ud801\uDC00。其实,我们遍历一个字符串,遍历的是这个字符串中所有代码点,而
s.length()
返回的是字符串s中代码单元的个数。当i对应的代码单元只是一个32位代码点的一部分时,
s.charAt(i)
也就不能像我们希望的那样工作了。
下面给出了几种正确遍历一个字符串的方法:
package testchar; /**
* 正确遍历String
*
* @author yuncong
*
*/
public class TestChar { public static void main(String[] args) {
String s = "\u0041\u00DF\u6771\ud801\uDC00";
// 获得字符串中代码点的数量
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中的辅助字符)
java 遍历String的更多相关文章
- java 遍历map 方法 集合 五种的方法
package com.jackey.topic; import java.util.ArrayList;import java.util.HashMap;import java.util.Itera ...
- java中String类型变量的赋值问题
第一节 String类型的方法参数 运行下面这段代码,其结果是什么? package com.test; public class Example { String str = new String( ...
- java 遍历文件夹里的文件
Java遍历文件夹的2种方法: A.不使用递归: import java.io.File; import java.util.LinkedList; public class FileSystem { ...
- JAVA 遍历文件夹下的所有文件
JAVA 遍历文件夹下的所有文件(递归调用和非递归调用) 1.不使用递归的方法调用. public void traverseFolder1(String path) { int fileNum = ...
- java遍历树(深度遍历和广度遍历
java遍历树如现有以下一颗树:A B B1 B11 B2 B22 C C ...
- 解决spring mvc 上传报错,Field [] isn't an enum value,Failed to convert value of type 'java.lang.String[]' to required type '
没有选择附件,但是点击上传按钮的时候会报错. 之前不选择文件,直接上传空文件是可以的,后来不知道改了什么就不行了. 错误信息: -- :: [http--] TRACE org.springframe ...
- java遍历Hashmap/Hashtable的几种方法
一>java遍历Hashtabe: import java.util.Hashtable; import java.util.Set; public class HashTableTest { ...
- JAVA 遍历文件夹下的所有文件(递归调用和非递归调用)
JAVA 遍历文件夹下的所有文件(递归调用和非递归调用) 1.不使用递归的方法调用. public void traverseFolder1(String path) { int fileNum = ...
- java 遍历List 和 Map的几种方法
java遍历List 1.(性能最差) for(String tmp:list) { //System.out.println(tmp); } 2.(性能最好) for(int i = 0; i &l ...
随机推荐
- IntelliJ IDEA 学习(四)Idea逆向生成数据库实体类
第一步配置 数据库 第二步 配置hibernate,如果没有cfg.xml文件,点击ok后会自动生成 第三步 选择hibernate配置文件生成实体 第四步 设置完点击,选中要生成的实体的表 注意: ...
- A-Z排序控件的实现
前言 最近项目需要做一个地区首字母a-z排序的效果,记录一下自己如何实现的. 先看下效果图: 分析 这种效果自己实现还是第一次;之前见过这种效果: 这些字母都是onDraw画上去的;只要知道每个字母的 ...
- Loadrunner关于页面检查的几个函数详解
环境:Loadrunner版本:8.0自建一个test.html文件:<html><head><meta name="google1" content ...
- Docker exec与Docker attach
转载博客地址:http://blog.csdn.net/halcyonbaby 新浪微博:@寻觅神迹 内容系本人学习.研究和总结,如有雷同,实属荣幸! ================== Docke ...
- Codeforces 8D Two Friends 三分+二分+计算几何
题目链接:点击打开链接 题意:点击打开链接 三分house到shop的距离,二分这条斜边到cinema的距离 #include<stdio.h> #include<string.h& ...
- 一些制作app的软件
搜狐快站 http://www.kuaizhan.com/百度siteapp http://siteapp.baidu.com/腾讯风铃 http://fl.qq.com/
- C# 取时间段年、月、日、季度
DateTime dt = DateTime.Now; //当前时间 DateTime startWeek = dt.AddDays(1 - Convert.ToInt32( ...
- MBProgressHUD 设置透明背景
MBProgressHUD 默认使用MBProgressHUDBackgroundStyleBlur 类型 MBProgressHUDBackgroundStyleBlur使用了毛玻璃效果 ,我们要把 ...
- C#7.0之元组数据
static (string,string,string) LookupName(int a) { return ("","",""); } ...
- mybatis想要在控制台显示sql语句配置文件
在src目录下创建一个properties文件 配置内容如下 log4j.rootLogger=debug,stdout,logfile log4j.appender.stdout=org.apach ...