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 遍历String相关推荐

  1. java map 迭代遍历_java 遍历Map的四种方式

    java 遍历Map的四种方式 CreationTime--2018年7月16日16点15分 Author:Marydon 一.迭代key&value 第一种方式:迭代entrySet 1.方 ...

  2. java中string类_Java中String类浅谈

    1)String对象的初始化 由于String对象特别常用,所以在对String对象进行初始化时,Java提供了一种简化的特殊语法,格式如下:      String s = "abc&qu ...

  3. java new string 图_Java中String直接赋字符串和new String的一些问题

    今天课堂测试做了几道String的练习题,做完直接心态爆炸...... 整理自下面两篇博客: 首先先来看看下面的代码: public classStringTest {public static vo ...

  4. java中的string函数_java中string.trim()函数的作用实例及源码

    trim()的作用:去掉字符串首尾的空格. public static void main(String arg[]){ String a=" hello world "; Str ...

  5. java replaceall函数_java基础—-String中replace和replaceAll方法

    这里面我们分析一下replace与replaceAll方法的差异以及原理. replace各个方法的定义 一.replaceFirst方法 public String replaceFirst(Str ...

  6. java string 字节_java中string究竟占多少字节

    以前学java基础的时候考虑过string占多少字节,百度后有人说一个汉字占两个字节,所以一个string的字节数是可变的,遇到一个汉字+2,遇到一个字母+1.笔者对此结论严重怀疑,一个string在 ...

  7. java 实现 string类_java 中String类的常用方法总结,带你玩转String类。

    String类: String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.String类对象创建后不能修改,StringBuffer & St ...

  8. java 树的层次遍历_Java遍历树的层级 - osc_jegm3yg5的个人空间 - OSCHINA - 中文开源技术交流社区...

    非科班出身,欢迎指正. 要实现的逻辑是,在一棵树中,给出任意一个节点,获取到该节点下的N个层级. 一.树型结构 下图的树中,节点上的字母代表节点的名字,字母下的代表该节点的下单金额. 二.数据准备 组 ...

  9. java string类型_java中String类型

    String类型是字符串类型..字符串一旦创建不可以在改变."abc"字符串对象一旦创建,不可以再改成"abcd" 提升字符串的访问效率:在程序中使用了&quo ...

最新文章

  1. 关于人工智能工程可能不知的7件事
  2. 2007年3月东北微软技术活动预告
  3. VC中CListCtrl中的LVCOLUMN和LVITEM详细介绍
  4. 通知传值(NSNotificationCenter)
  5. 设计模式笔记之七 (桥接模式)
  6. python数据分析包pandas_Python 数据分析包:pandas 基础
  7. idea+SpringBoot+Mybatis+Mysql环境搭建
  8. linux先安装svn server
  9. kt条件例题运筹学_2016年山东大学管理学院运筹学(线性规划部分)之运筹学基础及应用(同等学力加试)复试笔试最后押题五套卷...
  10. java高级工程师哪些技术要掌握?
  11. delphi调用https
  12. 七个非常好用的黑科技APP,免费/小众/超实用,一次性全给你
  13. 看我如何抓取最新房价数据
  14. TestStand-从LabVIEW创建TestStand数据类型的簇
  15. 算法入门:日期计算(附蓝桥杯)
  16. Qlist+QMap+QVariant使用
  17. 透视变换--点对应变换
  18. nvm 安裝不同版本的node(詳細過程无图)
  19. 百度安全查询,查询网址是否存在百度安全风险的方法
  20. 写markdown博客如何将截图快速上传到图床——记一个工具插件的实现(windows版 开源)...

热门文章

  1. 固态继电器的五大优势
  2. 解决设备管理器,控制面板中管理工具无法打开的问题
  3. 【建模算法】dbscan算法(python实现)
  4. 使用Jedis连接Redis失败的几个注意点
  5. red学习 --- rebol语言
  6. JavaScript的迭代器与生成器
  7. Vue3时间轴(Timeline)
  8. 迅为2K1000龙芯开发板PMON 开发
  9. linux soundwire usb,Soundwire Server
  10. VB如何使用计时器?