【问题标题】:Clarification on how character encodings work澄清字符编码的工作原理
【发布时间】:2021-03-30 15:32:51
【问题描述】:

我正在编写一个程序来根据字母(即“abc”= a+b+c = 1+2+3 = 6)获取单词的“总和”。我正在使用total += (int) char - 'a' + 1(在Java中)的方法。该程序不区分大小写('A' = 'a'),所以首先我想在必要时将 char 转换为小写。我写了

if (char < 'a') {char += 32;}

在 UTF-16 和 ASCII 中是正确的,但不是 UTF-8。

我的问题是,如果我要发布这段代码,编码在编译后是如何工作的?如果用户使用的是UTF-8,程序会失败(所以最好使用Character.toLowerCase()),或者由于程序是Java,程序中的任何字符都将是程序的编码,因此可以工作?

如果不清楚,我不知道我在说什么,所以一些关于编码如何工作的一般信息也会很棒。

【问题讨论】:

  • Java 默认使用 UTF-16,但您可以在构造函数中设置字符串的字符集。您可以使用 String.toLowerCase 使其不区分大小写。以下是标准 ASCII 字符值表:asciitable.com 这基本上就是您想要使用的。
  • 不能设置字符串的字符集,它是UTF-16。您可以声明用于初始化字符串的字节数组的字符集;这告诉运行时如何转换为 UTF-16。
  • 为什么不使用现有的hash function 而不是自己发明呢? String::hashCode 返回一个 int
  • @BasilBorque - 这不是他想要做的。他似乎想用特定的值替换特定的字母。

标签: java unicode character-encoding ascii


【解决方案1】:

Java 字符串始终以 UTF-16 编码;输入和输出根据需要进行转换。

然而,这可以写得更好:

 if (char < 'a') {char += 32;}

作为

 if (ch >= 'A' && ch <= 'Z')
    ch += ('a' - 'A');

原因:

  1. 检查预期范围只是更加谨慎

  2. 您不需要“知道”小写字母和大写字母之间的距离是 32。

另外,'char' 是 Java 中的关键字。

这当然只适用于非重音美国/英国字母表中的字母。

但是,我建议您使用(正如您自己所说的)'toLowerCase()',因为这就是它的用途 - 让您摆脱细节。

【讨论】:

  • 我实际上并没有使用char作为名称,它只是我复杂变量名称的占位符
  • 通过减法更改为小写适用于 A-Z,但通常不是。如果要支持 A-Z 以外的字母,则需要使用大小写映射功能。
  • 然后你必须担心有多个小写表示的字母:Σ 映射到 σ 或 ς。
  • 虽然没有 API 更改,但自 Java 9 以来,“Java 字符串始终以 UTF-16 编码” 的说法并不正确。请参阅 JEP 400 和 this SO answer 对问题 “Java 对 String 的内部表示形式是什么?修改后的 UTF-8?UTF-16?”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 2011-03-07
  • 2012-01-27
  • 1970-01-01
  • 2023-03-27
相关资源
最近更新 更多