ICU-21397 Allow null to unset options in Java NumberRangeFormatter
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java
index 13734e1..6843f5e 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java
@@ -149,41 +149,37 @@
// of a MacroProps object at each step.
// TODO: Remove the reference to the parent after the macros are resolved?
RangeMacroProps macros = new RangeMacroProps();
+ // Bitmap: 1 if seen; 0 if unseen
+ long seen = 0;
NumberRangeFormatterSettings<?> current = this;
while (current != null) {
+ long keyBitmask = (1L << current.key);
+ if (0 != (seen & keyBitmask)) {
+ current = current.parent;
+ continue;
+ }
+ seen |= keyBitmask;
switch (current.key) {
case KEY_MACROS:
// ignored for now
break;
case KEY_LOCALE:
- if (macros.loc == null) {
- macros.loc = (ULocale) current.value;
- }
+ macros.loc = (ULocale) current.value;
break;
case KEY_FORMATTER_1:
- if (macros.formatter1 == null) {
- macros.formatter1 = (UnlocalizedNumberFormatter) current.value;
- }
+ macros.formatter1 = (UnlocalizedNumberFormatter) current.value;
break;
case KEY_FORMATTER_2:
- if (macros.formatter2 == null) {
- macros.formatter2 = (UnlocalizedNumberFormatter) current.value;
- }
+ macros.formatter2 = (UnlocalizedNumberFormatter) current.value;
break;
case KEY_SAME_FORMATTERS:
- if (macros.sameFormatters == -1) {
- macros.sameFormatters = (boolean) current.value ? 1 : 0;
- }
+ macros.sameFormatters = (boolean) current.value ? 1 : 0;
break;
case KEY_COLLAPSE:
- if (macros.collapse == null) {
- macros.collapse = (RangeCollapse) current.value;
- }
+ macros.collapse = (RangeCollapse) current.value;
break;
case KEY_IDENTITY_FALLBACK:
- if (macros.identityFallback == null) {
- macros.identityFallback = (RangeIdentityFallback) current.value;
- }
+ macros.identityFallback = (RangeIdentityFallback) current.value;
break;
default:
throw new AssertionError("Unknown key: " + current.key);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java
index 0788513..02ffbfc 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java
@@ -665,6 +665,26 @@
}
@Test
+ public void test21397_UnsetNull() {
+ assertFormatRange(
+ "Unset identity fallback",
+ NumberRangeFormatter.with()
+ .identityFallback(RangeIdentityFallback.RANGE)
+ .identityFallback(null),
+ new ULocale("en-us"),
+ "1–5",
+ "~5",
+ "~5",
+ "0–3",
+ "~0",
+ "3–3,000",
+ "3,000–5,000",
+ "4,999–5,001",
+ "~5,000",
+ "5,000–5,000,000");
+ }
+
+ @Test
public void testPlurals() {
// Locale sl has interesting plural forms:
// GBP{