All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.icu.number.CompactNotation Maven / Gradle / Ivy

Go to download

International Component for Unicode for Java (ICU4J) is a mature, widely used Java library providing Unicode and Globalization support

There is a newer version: 76.1
Show newest version
// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.number;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.ibm.icu.impl.StandardPlural;
import com.ibm.icu.impl.number.CompactData;
import com.ibm.icu.impl.number.CompactData.CompactType;
import com.ibm.icu.impl.number.DecimalFormatProperties;
import com.ibm.icu.impl.number.DecimalQuantity;
import com.ibm.icu.impl.number.MicroProps;
import com.ibm.icu.impl.number.MicroPropsGenerator;
import com.ibm.icu.impl.number.MutablePatternModifier;
import com.ibm.icu.impl.number.MutablePatternModifier.ImmutablePatternModifier;
import com.ibm.icu.impl.number.PatternStringParser;
import com.ibm.icu.impl.number.PatternStringParser.ParsedPatternInfo;
import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.util.ULocale;

/**
 * A class that defines the scientific notation style to be used when formatting numbers in
 * NumberFormatter.
 *
 * 

* This class exposes no public functionality. To create a CompactNotation, use one of the factory * methods in {@link Notation}. * * @stable ICU 60 * @see NumberFormatter */ public class CompactNotation extends Notation { final CompactStyle compactStyle; final Map> compactCustomData; /** * Create a compact notation with custom data. * @internal * @deprecated This API is ICU internal only. * @see DecimalFormatProperties#setCompactCustomData */ @Deprecated public static CompactNotation forCustomData(Map> compactCustomData) { return new CompactNotation(compactCustomData); } /* package-private */ CompactNotation(CompactStyle compactStyle) { compactCustomData = null; this.compactStyle = compactStyle; } /* package-private */ CompactNotation(Map> compactCustomData) { compactStyle = null; this.compactCustomData = compactCustomData; } /* package-private */ MicroPropsGenerator withLocaleData( ULocale locale, String nsName, CompactType compactType, PluralRules rules, MutablePatternModifier buildReference, boolean safe, MicroPropsGenerator parent) { // TODO: Add a data cache? It would be keyed by locale, nsName, compact type, and compact style. return new CompactHandler(this, locale, nsName, compactType, rules, buildReference, safe, parent); } private static class CompactHandler implements MicroPropsGenerator { final PluralRules rules; final MicroPropsGenerator parent; final Map precomputedMods; final MutablePatternModifier unsafePatternModifier; final CompactData data; private CompactHandler( CompactNotation notation, ULocale locale, String nsName, CompactType compactType, PluralRules rules, MutablePatternModifier buildReference, boolean safe, MicroPropsGenerator parent) { this.rules = rules; this.parent = parent; this.data = new CompactData(); if (notation.compactStyle != null) { data.populate(locale, nsName, notation.compactStyle, compactType); } else { data.populate(notation.compactCustomData); } if (safe) { // Safe code path precomputedMods = new HashMap<>(); precomputeAllModifiers(buildReference); unsafePatternModifier = null; } else { // Unsafe code path precomputedMods = null; unsafePatternModifier = buildReference; } } /** Used by the safe code path */ private void precomputeAllModifiers(MutablePatternModifier buildReference) { Set allPatterns = new HashSet<>(); data.getUniquePatterns(allPatterns); for (String patternString : allPatterns) { ParsedPatternInfo patternInfo = PatternStringParser.parseToPatternInfo(patternString); buildReference.setPatternInfo(patternInfo, NumberFormat.Field.COMPACT); precomputedMods.put(patternString, buildReference.createImmutable()); } } @Override public MicroProps processQuantity(DecimalQuantity quantity) { MicroProps micros = parent.processQuantity(quantity); assert micros.rounder != null; // Treat zero, NaN, and infinity as if they had magnitude 0 int magnitude; int multiplier = 0; if (quantity.isZeroish()) { magnitude = 0; micros.rounder.apply(quantity); } else { multiplier = micros.rounder.chooseMultiplierAndApply(quantity, data); magnitude = quantity.isZeroish() ? 0 : quantity.getMagnitude(); magnitude -= multiplier; } StandardPlural plural = quantity.getStandardPlural(rules); String patternString = data.getPattern(magnitude, plural); if (patternString == null) { // Use the default (non-compact) modifier. // No need to take any action. } else if (precomputedMods != null) { // Safe code path. // Java uses a hash set here for O(1) lookup. C++ uses a linear search. ImmutablePatternModifier mod = precomputedMods.get(patternString); mod.applyToMicros(micros, quantity); } else { // Unsafe code path. // Overwrite the PatternInfo in the existing modMiddle. ParsedPatternInfo patternInfo = PatternStringParser.parseToPatternInfo(patternString); unsafePatternModifier.setPatternInfo(patternInfo, NumberFormat.Field.COMPACT); unsafePatternModifier.setNumberProperties(quantity.signum(), null); micros.modMiddle = unsafePatternModifier; } // Change the exponent only after we select appropriate plural form // for formatting purposes so that we preserve expected formatted // string behavior. quantity.adjustExponent(-1 * multiplier); // We already performed rounding. Do not perform it again. micros.rounder = null; return micros; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy