Почему Java Character.toUpperCase/toLowerCase не имеет параметра Locale, такого как String.toUpperCase/toLowerCase

Мне интересно, почему Character.toUpperCase/toLowerCase не имеет параметра Locale, такого как String.toUpperCase/toLowerCase.

Я должен сначала прописные буквы текста, который может быть на любом языке. У меня есть 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/toLowerCase и String.toUpperCase/toLowerCase нет большой разницы, потому что String - это массив символов.


person Loc    schedule 22.10.2014    source источник
comment
Обратите внимание, что javadoc предлагает использовать версию String для сопоставлений, чувствительных к локали.   -  person Sotirios Delimanolis    schedule 22.10.2014


Ответы (4)


Из Character#toUpperCase(int) Джавадок,

Как правило, String.toUpperCase() следует использовать для преобразования символов в верхний регистр. String методы отображения случаев имеют несколько преимуществ по сравнению с Character методами отображения случаев. Методы сопоставления регистра String могут выполнять сопоставления с учетом локали, контекстно-зависимые сопоставления и сопоставления символов 1:M, тогда как методы сопоставления регистра Character не могут.

Итак, ответ — ваш второй пример (String.toUpperCase)

person Elliott Frisch    schedule 22.10.2014
comment
опереди меня на 6 секунд! - person dkatzel; 22.10.2014
comment
Поэтому я не должен использовать Character.toUpperCase/toLowerCase, поскольку мой текст может быть на любом языке. Спасибо! - person Loc; 22.10.2014
comment
Всегда ли Character.toUpperCase('i') запускает Locale.US или systemLocale? Скажем, запуск i -> I в локали США, но турецкий дает i -> \u0130 согласно String Javadocs. - person Whome; 29.11.2015

Как говорит Javadoc:

В общем, String.toUpperCase() следует использовать для преобразования символов в верхний регистр. Методы сопоставления регистра строк имеют несколько преимуществ по сравнению с методами сопоставления регистра символов. Методы сопоставления регистра строк могут выполнять сопоставления с учетом локали, контекстно-зависимые сопоставления и сопоставления символов 1:M, в то время как методы сопоставления регистра символов не могут.

Так что используйте String.toUppercase()

person dkatzel    schedule 22.10.2014

Если вопрос "какой метод следует использовать", то этот вопрос является дубликатом преобразования строки в регистр заголовка и правильного ответа ЛИБО

Если возникает вопрос «почему Character не имеет методов изменения регистра, зависящих от локали», то единственный способ получить ответ — это проконсультироваться с одним из разработчиков языка Java. Маловероятно, что сообщество Stack Overflow сможет дать вам нужный ответ.

person Dawood ibn Kareem    schedule 22.10.2014
comment
Фактически. У меня есть 2 подвопроса, как вы знаете. Какой способ использовать - у меня есть ответ от Elliott Frisch и dkatzel. Другой вопрос, почему у Character.toUpperCase/toLowerCase нет параметра Locale - я спрашиваю об этом, потому что, возможно, есть другая причина, по которой Locale не нужен. - person Loc; 22.10.2014
comment
Да, этот другой вопрос касается моего последнего абзаца. Однако в будущем, если у вас есть два вопроса, вы должны задать два вопроса. Это облегчает принятие ответа, если для каждого подвопроса лучше всего подходят разные ответы. - person Dawood ibn Kareem; 22.10.2014
comment
Определенно Locale нужен для изменения регистра отдельного символа. Например, результат преобразования i в верхний регистр отличается для английского и турецкого языков. - person Dawood ibn Kareem; 22.10.2014
comment
да. У меня была такая же мысль, но я не уверен, почему у Character нет для этого API. - person Loc; 22.10.2014
comment
Как говорится в моем ответе, вам придется проконсультироваться с одним из разработчиков Java. Это выходит за рамки возможностей Stack Overflow для ответа. - person Dawood ibn Kareem; 22.10.2014

Здесь я объясню некоторые проблемы, связанные с поддержкой версий ToUpperCase и ToLowerCase для chars, в дополнение к Strings, которые параметр локали не решит:

  1. Версия char в верхнем или нижнем регистре может быть строкой, охватывающей более одного char. Примером может служить немецкое ß, расширяющееся до SS в верхнем регистре.

  2. char — это 16-битное значение, но не все символы Юникода (и даже не все буквы Юникода) могут поместиться в 16-битное char. Таким образом, char версия ToUpperCase и ToLowerCase не будет поддерживать весь репертуар символов Unicode.

  3. Некоторые преобразования отображения регистра (например, греческая сигма) зависят от контекста; то есть, какие символы идут до или после рассматриваемого символа. Версия char ToUpperCase и ToLowerCase не будет иметь такого рода доступного контекста.

person Peter O.    schedule 06.01.2020