在Android中,使用java:确定字符串长度为mix-bytes的字符串?

时间:2012-06-14 09:08:53

标签: java android

有一个String变量,包含ascii字符和双字节字符(例如,Chinese,Japanese,...)。

如何确定String的总长度?另外,我想用字符串substring / replace函数实现。

4 个答案:

答案 0 :(得分:6)

Java中的字符串类型隐式为UTF-16。所有其他编码(例如UTF-8)应使用byte数组表示。

“长度”是一个含糊不清的术语。

每个Unicode代码点将使用一个或两个代码单位(16位char s) - 基本多语言平面和补充范围。当转码为不同的编码时,字符串将消耗的字节数可以改变。一系列代码点也可以组合在一起形成一个用户可见的字形。

所以,这里有一些方法来衡量一个字符串的“长度”:

我在a blog post中介绍了部分内容。


  

评论:是否有一种简单的方法/ API来处理混合字节字符串?   (剪切/缩短/ substring()字符串,如“sDDsssDDDDsDD”(s:单   字节ascii字符,DD:双字节字符)?

考虑Java字符串文字"Hello 您好世界",也可以表示为"Hello \u60a8\u597d\u4e16\u754c"

这可以在传统的Windows Simplified Chinese双字节编码中编码为字节序列:

48 65 6c 6c 6f 20 c4 fa ba c3 ca c0 bd e7

为了将其转换为Java字符,您需要对其进行解码:

byte[] data = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, (byte) 0xc4,
    (byte) 0xfa, (byte) 0xba, (byte) 0xc3, (byte) 0xca, (byte) 0xc0,
    (byte) 0xbd, (byte) 0xe7 };
Charset encoding = Charset.forName("x-mswin-936");
String hello = new String(data, encoding);

现在您已将数据转码为Unicode,您可以使用常用的字符串操作机制(substringregex matching等)。

请注意,您必须知道转换前使用的双字节编码。如果你不知道编码,你所拥有的只是垃圾。

我不知道Android支持哪些编码,但您可以通过调用Charset.availableCharsets()在运行时发现这一点。如果Android不支持您需要的编码,请查看ICU4J库。

答案 1 :(得分:4)

Java字符串是字符,而不是字节。长度是字符数。如果需要字节数,请使用

str.getBytes(encoding).length

其中编码例如是“UTF-8”。

答案 2 :(得分:4)

正如其他人所说,Java Strings是概念上只读的Java字符数组,String的“长度”是字符数。但是,有一些复杂的问题:

  • Java角色不一定是您认为的角色。特别是,可以使用Java字符表示更多的Unicode字符(代码点)。某些Unicode代码点需要两个Java字符来表示它们。 (这是Thilo所指的“扩展平面”问题。)

  • 某些JVM(启动时设置了相应的JVM标志)将使用字符串表示,其中字符以UTF-8编码。虽然String的长度是相同的(在这种情况下,UTF-8表示的Java字符数),但使用的内存可能会少得多。

然后有一个问题是需要多少字节才能将字符串的字符表示为UTF-8或其他一些编码。据我所知,唯一能找到答案的JVM就是进行转换;例如使用getBytes(charSet)

最后,问题是String在堆中占用了多少字节。您可以找出String对象及其关联的char[]支持对象中有多少字节。但是,当您考虑substring和其他String方法可以创建共享单个支持数组的字符串集时,预测将会发生什么可能会非常棘手。< / p>

答案 3 :(得分:0)

Java在内部使用Unicode,因此实际字符是什么并不重要。 String.length()会给你正确的长度。其他String方法也是如此。