【问题标题】:Why Java Character.toUpperCase/toLowerCase has no Locale parameter like String.toUpperCase/toLowerCase为什么 Java Character.toUpperCase/toLowerCase 没有像 String.toUpperCase/toLowerCase 这样的 Locale 参数
【发布时间】:2014-10-22 18:59:11
【问题描述】:

我想知道为什么 Character.toUpperCase/toLowerCase 没有像 String.toUpperCase/toLowerCase 这样的 Locale 参数。

我必须首先将可以是任何语言的文本大写。我有 2 个解决方案:

  1. 使用Character.toUpperCase

    String text = "stack overflow";
    StringBuilder sb = new StringBuilder(text);   
    
    sb.setCharAt(0, Character.toUpperCase(sb.charAt(0))); // No Locale parameter here.
    
    String out = sb.toString(); //Out: Stack overflow
    
  2. 使用String.toUpperCase

    Locale myLocale = new Locale(locateId);
    
    String text = "stack overflow";
    String text1 = text.substring(0,1).toUpperCase(myLocale );
    String text2 = text.substring(1);
    
    String out = text1 + text2; // Out: Stack overflow
    

对于我的语言环境。两种方式的结果相同。

我的问题是:

  • 因为文本可以是任何语言。我应该使用哪种方式?

  • 为什么Character.toUpperCase/toLowerCase 没有Locale 参数,因为Character.toUpperCase/toLowerCaseString.toUpperCase/toLowerCase 之间没有太大区别,因为String 是字符数组。

【问题讨论】:

  • 请注意,javadoc 建议使用String 的版本进行区域敏感映射。

标签: java locale multilingual uppercase lowercase


【解决方案1】:

这里我将解释一些与支持chars 的ToUpperCaseToLowerCase 版本有关的一些问题,除了Strings,语言环境参数无法解决:

  1. char 的大写或小写版本可能是跨越多个 char 的字符串。一个例子是德语的ß 扩展为大写版本的SS

  2. char 是一个 16 位值,但并非所有 Unicode 字符(甚至不是所有 Unicode 字母)都适合 16 位 char。因此,ToUpperCaseToLowerCasechar 版本将不支持整个 Unicode 字符库。

  3. 某些大小写映射转换(例如希腊语 sigma)取决于上下文;也就是说,有问题的字符之前或之后出现了什么样的字符。 char 版本的 ToUpperCase 和 ToLowerCase 将没有这种可用的上下文。

【讨论】:

    【解决方案2】:

    来自Character#toUpperCase(int)Javadoc,

    一般来说,String.toUpperCase() 应该用于将字符映射为大写。 String 案例映射方法比 Character 案例映射方法有几个好处。 String 大小写映射方法可以执行区域敏感映射、上下文敏感映射和 1:M 字符映射,而 Character 大小写映射方法不能。

    所以,答案是您的第二个示例 (String.toUpperCase)

    【讨论】:

    • 领先我 6 秒!
    • 所以我不应该使用 Character.toUpperCase/toLowerCase 因为我的文本可以是任何语言。谢谢!
    • Character.toUpperCase('i') 是否总是运行 Locale.US 或 systemLocale?假设在美国语言环境中运行 i -> I,但根据 String Javadocs,土耳其语给出 i -> \u0130
    【解决方案3】:

    正如 Javadoc 所说:

    一般来说,应该使用 String.toUpperCase() 将字符映射为大写。字符串大小写映射方法比字符大小写映射方法有几个好处。字符串大小写映射方法可以执行区域敏感映射、上下文敏感映射和 1:M 字符映射,而字符大小写映射方法不能。

    所以使用 String.toUppercase()

    【讨论】:

      【解决方案4】:

      如果问题是“我应该使用哪种方法”,那么这个问题与String conversion to Title Case 重复,正确答案是EITHER

      如果问题是“为什么Character 没有区分区域设置的大小写更改方法”,那么您可能得到答案的唯一方法是咨询 Java 语言的设计者之一。 Stack Overflow 社区不太可能给你想要的答案。

      【讨论】:

      • 其实。如您所知,我有两个子问题。使用哪种方式 - 我从 Elliott Frisch 和 dkatzel 那里得到了答案。其他为什么 Character.toUpperCase/toLowerCase 没有 Locale 参数的问题 - 我问这个是因为可能还有另一个不需要 Locale 的原因。
      • 是的,“其他问题”是我最后一段所要解决的问题。但是,将来,如果您有两个问题,则应该问两个问题。如果每个子问题都有不同的答案是“最好的”,那么接受答案会更容易。
      • 绝对需要 Locale 来更改单个字符的大小写。例如,将i 转换为大写的结果在英语和土耳其语之间是不同的。
      • 是的。我也有同样的想法,但不确定为什么 Character 没有 API。
      • 就像我的回答所说,您必须咨询 Java 的设计者之一。这超出了 Stack Overflow 的回答能力。
      猜你喜欢
      • 2017-08-15
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-18
      相关资源
      最近更新 更多