RFR: 8365675: Add String Unicode Case-Folding Support [v10]
Roger Riggs
rriggs at openjdk.org
Mon Nov 24 14:25:41 UTC 2025
On Fri, 21 Nov 2025 23:56:05 GMT, Xueming Shen <sherman at openjdk.org> wrote:
>> ### Summary
>>
>> Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions.
>>
>> Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as:
>>
>> **String.equalsIgnoreCase(String)**
>>
>> - Unicode-aware, locale-independent.
>> - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point.
>> - Limited: does not support 1:M mapping defined in Unicode case folding.
>>
>> **Character.toLowerCase(int) / Character.toUpperCase(int)**
>>
>> - Locale-independent, single code point only.
>> - No support for 1:M mappings.
>>
>> **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)**
>>
>> - Based on Unicode SpecialCasing.txt, supports 1:M mappings.
>> - Intended primarily for presentation/display, not structural case-insensitive matching.
>> - Requires full string conversion before comparison, which is less efficient and not intended for structural matching.
>>
>> **1:M mapping example, U+00DF (ß)**
>>
>> - String.toUpperCase(Locale.ROOT, "ß") → "SS"
>> - Case folding produces "ss", matching Unicode caseless comparison rules.
>>
>>
>> jshell> "\u00df".equalsIgnoreCase("ss")
>> $22 ==> false
>>
>> jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss")
>> $24 ==> true
>>
>>
>> ### Motivation & Direction
>>
>> Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching.
>>
>> - Unicode-compliant **full** case folding.
>> - Simpler, stable and more efficient case-less matching without workarounds.
>> - Brings Java's string comparison handling in line with other programming languages/libraries.
>>
>> This PR proposes to introduce the following comparison methods in `String` class
>>
>> - boolean equalsFoldCase(String anotherString)
>> - int compareToFoldCase(String anotherString)
>> - Comparator<String> UNICODE_CASEFOLD_ORDER
>>
>> These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required.
>>
>> *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string.
>> However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then pass...
>
> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision:
>
> doc update - add spec tag
Looks good, a couple of javadoc formatting changes would clean up the formatted javadoc.
src/java.base/share/classes/java/lang/String.java line 2243:
> 2241: * per-character mapping performed by {@code equalsIgnoreCase}.
> 2242: * For example:
> 2243: * <pre>{@snippet lang=java :
<pre> and </pre> are unnecessary, @snippet handles the formatting.
src/java.base/share/classes/java/lang/String.java line 2445:
> 2443: * {@code compareToIgnoreCase}.
> 2444: * For example:
> 2445: * <pre>{@snippet lang=java :
<pre> and </pre> are redundant and should be removed. @snippet handles all the formatting.
-------------
PR Review: https://git.openjdk.org/jdk/pull/27628#pullrequestreview-3500569860
PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2556436806
PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2556430920
More information about the build-dev
mailing list