FileDocCategorySizeDatePackage
ChoiceFormat.javaAPI DocAndroid 1.5 API18003Wed May 06 22:41:06 BST 2009java.text

ChoiceFormat

public class ChoiceFormat extends NumberFormat
Returns a fixed string based on a numeric value. The class can be used in conjunction with the {@link MessageFormat} class to handle plurals in messages. {@code ChoiceFormat} enables users to attach a format to a range of numbers. The choice is specified with an ascending list of doubles, where each item specifies a half-open interval up to the next item as in the following: X matches j if and only if {@code limit[j] <= X < limit[j+1]}.

If there is no match, then either the first or last index is used. The first or last index is used depending on whether the number is too low or too high. The length of the format array must be the same as the length of the limits array.

Examples:
double[] limits = {1, 2, 3, 4, 5, 6, 7};
String[] fmts = {"Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"};

double[] limits2 = {0, 1, ChoiceFormat.nextDouble(1)};
String[] fmts2 = {"no files", "one file", "many files"};

ChoiceFormat.nextDouble(double) allows to get the double following the one passed to the method. This is used to create half open intervals.

{@code ChoiceFormat} objects also may be converted to and from patterns. The conversion can be done programmatically, as in the example above, or by using a pattern like the following:

"1#Sun|2#Mon|3#Tue|4#Wed|5#Thur|6#Fri|7#Sat"
"0#are no files|1#is one file|1<are many files"

where:

  • "#" specifies an inclusive limit value;
  • "<" specifies an exclusive limit value.
since
Android 1.0

Fields Summary
private static final long
serialVersionUID
private double[]
choiceLimits
private String[]
choiceFormats
Constructors Summary
public ChoiceFormat(double[] limits, String[] formats)
Constructs a new {@code ChoiceFormat} with the specified double values and associated strings. When calling {@link #format(double, StringBuffer, FieldPosition) format} with a double value {@code d}, then the element {@code i} in {@code formats} is selected where {@code i} fulfills {@code limits[i] <= d < limits[i+1]}.

The length of the {@code limits} and {@code formats} arrays must be the same.

param
limits an array of doubles in ascending order. The lowest and highest possible values are negative and positive infinity.
param
formats the strings associated with the ranges defined through {@code limits}. The lower bound of the associated range is at the same index as the string.
since
Android 1.0


                                                                                                                                                                                 
         
        setChoices(limits, formats);
    
public ChoiceFormat(String template)
Constructs a new {@code ChoiceFormat} with the strings and limits parsed from the specified pattern.

param
template the pattern of strings and ranges.
exception
IllegalArgumentException if an error occurs while parsing the pattern.
since
Android 1.0

        applyPattern(template);
    
Methods Summary
public voidapplyPattern(java.lang.String template)
Parses the pattern to determine new strings and ranges for this {@code ChoiceFormat}.

param
template the pattern of strings and ranges.
exception
IllegalArgumentException if an error occurs while parsing the pattern.
since
Android 1.0

        double[] limits = new double[5];
        List<String> formats = new ArrayList<String>();
        int length = template.length(), limitCount = 0, index = 0;
        StringBuffer buffer = new StringBuffer();
        NumberFormat format = NumberFormat.getInstance(Locale.US);
        ParsePosition position = new ParsePosition(0);
        while (true) {
            index = skipWhitespace(template, index);
            if (index >= length) {
                if (limitCount == limits.length) {
                    choiceLimits = limits;
                } else {
                    choiceLimits = new double[limitCount];
                    System.arraycopy(limits, 0, choiceLimits, 0, limitCount);
                }
                choiceFormats = new String[formats.size()];
                for (int i = 0; i < formats.size(); i++) {
                    choiceFormats[i] = formats.get(i);
                }
                return;
            }

            position.setIndex(index);
            Number value = format.parse(template, position);
            index = skipWhitespace(template, position.getIndex());
            if (position.getErrorIndex() != -1 || index >= length) {
                // Fix Harmony 540
                choiceLimits = new double[0];
                choiceFormats = new String[0];
                return;
            }
            char ch = template.charAt(index++);
            if (limitCount == limits.length) {
                double[] newLimits = new double[limitCount * 2];
                System.arraycopy(limits, 0, newLimits, 0, limitCount);
                limits = newLimits;
            }
            double next;
            switch (ch) {
                case '#":
                case '\u2264":
                    next = value.doubleValue();
                    break;
                case '<":
                    next = nextDouble(value.doubleValue());
                    break;
                default:
                    throw new IllegalArgumentException();
            }
            if (limitCount > 0 && next <= limits[limitCount - 1]) {
                throw new IllegalArgumentException();
            }
            buffer.setLength(0);
            position.setIndex(index);
            upTo(template, position, buffer, '|");
            index = position.getIndex();
            limits[limitCount++] = next;
            formats.add(buffer.toString());
        }
    
public java.lang.Objectclone()
Returns a new instance of {@code ChoiceFormat} with the same ranges and strings as this {@code ChoiceFormat}.

return
a shallow copy of this {@code ChoiceFormat}.
see
java.lang.Cloneable
since
Android 1.0

        ChoiceFormat clone = (ChoiceFormat) super.clone();
        clone.choiceLimits = choiceLimits.clone();
        clone.choiceFormats = choiceFormats.clone();
        return clone;
    
public booleanequals(java.lang.Object object)
Compares the specified object with this {@code ChoiceFormat}. The object must be an instance of {@code ChoiceFormat} and have the same limits and formats to be equal to this instance.

param
object the object to compare with this instance.
return
{@code true} if the specified object is equal to this instance; {@code false} otherwise.
see
#hashCode
since
Android 1.0

        if (this == object) {
            return true;
        }
        if (!(object instanceof ChoiceFormat)) {
            return false;
        }
        ChoiceFormat choice = (ChoiceFormat) object;
        return Arrays.equals(choiceLimits, choice.choiceLimits)
                && Arrays.equals(choiceFormats, choice.choiceFormats);
    
public java.lang.StringBufferformat(double value, java.lang.StringBuffer buffer, java.text.FieldPosition field)
Appends the string associated with the range in which the specified double value fits to the specified string buffer.

param
value the double to format.
param
buffer the target string buffer to append the formatted value to.
param
field a {@code FieldPosition} which is ignored.
return
the string buffer.
since
Android 1.0

        for (int i = choiceLimits.length - 1; i >= 0; i--) {
            if (choiceLimits[i] <= value) {
                return buffer.append(choiceFormats[i]);
            }
        }
        return choiceFormats.length == 0 ? buffer : buffer
                .append(choiceFormats[0]);
    
public java.lang.StringBufferformat(long value, java.lang.StringBuffer buffer, java.text.FieldPosition field)
Appends the string associated with the range in which the specified long value fits to the specified string buffer.

param
value the long to format.
param
buffer the target string buffer to append the formatted value to.
param
field a {@code FieldPosition} which is ignored.
return
the string buffer.
since
Android 1.0

        return format((double) value, buffer, field);
    
public java.lang.Object[]getFormats()
Returns the strings associated with the ranges of this {@code ChoiceFormat}.

return
an array of format strings.
since
Android 1.0

        return choiceFormats;
    
public double[]getLimits()
Returns the limits of this {@code ChoiceFormat}.

return
the array of doubles which make up the limits of this {@code ChoiceFormat}.
since
Android 1.0

        return choiceLimits;
    
public inthashCode()
Returns an integer hash code for the receiver. Objects which are equal return the same value for this method.

return
the receiver's hash.
see
#equals
since
Android 1.0

        int hashCode = 0;
        for (int i = 0; i < choiceLimits.length; i++) {
            long v = Double.doubleToLongBits(choiceLimits[i]);
            hashCode += (int) (v ^ (v >>> 32)) + choiceFormats[i].hashCode();
        }
        return hashCode;
    
public static final doublenextDouble(double value)
Returns the double value which is closest to the specified double but larger.

param
value a double value.
return
the next larger double value.
since
Android 1.0

        if (value == Double.POSITIVE_INFINITY) {
            return value;
        }
        long bits;
        // Handle -0.0
        if (value == 0) {
            bits = 0;
        } else {
            bits = Double.doubleToLongBits(value);
        }
        return Double.longBitsToDouble(value < 0 ? bits - 1 : bits + 1);
    
public static doublenextDouble(double value, boolean increment)
Returns the double value which is closest to the specified double but either larger or smaller as specified.

param
value a double value.
param
increment {@code true} to get the next larger value, {@code false} to get the previous smaller value.
return
the next larger or smaller double value.
since
Android 1.0

        return increment ? nextDouble(value) : previousDouble(value);
    
public java.lang.Numberparse(java.lang.String string, java.text.ParsePosition position)
Parses a double from the specified string starting at the index specified by {@code position}. The string is compared to the strings of this {@code ChoiceFormat} and if a match occurs then the lower bound of the corresponding range in the limits array is returned. If the string is successfully parsed then the index of the {@code ParsePosition} passed to this method is updated to the index following the parsed text.

param
string the source string to parse.
param
position input/output parameter, specifies the start index in {@code string} from where to start parsing. See the Returns section for a description of the output values.
return
if one of the format strings of this {@code ChoiceFormat} instance is found in {@code string} starting at the index specified by {@code position.getIndex()} then
  • the index in {@code position} is set to the index following the parsed text;
  • the {@link java.lang.Double Double} corresponding to the format string is returned.

If none of the format strings is found in {@code string} then

  • the error index in {@code position} is set to the current index in {@code position};
  • {@link java.lang.Double#NaN Double.NaN} is returned.
since
Android 1.0

        int offset = position.getIndex();
        for (int i = 0; i < choiceFormats.length; i++) {
            if (string.startsWith(choiceFormats[i], offset)) {
                position.setIndex(offset + choiceFormats[i].length());
                return new Double(choiceLimits[i]);
            }
        }
        position.setErrorIndex(offset);
        return new Double(Double.NaN);
    
public static final doublepreviousDouble(double value)
Returns the double value which is closest to the specified double but smaller.

param
value a double value.
return
the next smaller double value.
since
Android 1.0

        if (value == Double.NEGATIVE_INFINITY) {
            return value;
        }
        long bits;
        // Handle 0.0
        if (value == 0) {
            bits = 0x8000000000000000L;
        } else {
            bits = Double.doubleToLongBits(value);
        }
        return Double.longBitsToDouble(value <= 0 ? bits + 1 : bits - 1);
    
public voidsetChoices(double[] limits, java.lang.String[] formats)
Sets the double values and associated strings of this ChoiceFormat. When calling {@link #format(double, StringBuffer, FieldPosition) format} with a double value {@code d}, then the element {@code i} in {@code formats} is selected where {@code i} fulfills {@code limits[i] <= d < limits[i+1]}.

The length of the {@code limits} and {@code formats} arrays must be the same.

param
limits an array of doubles in ascending order. The lowest and highest possible values are negative and positive infinity.
param
formats the strings associated with the ranges defined through {@code limits}. The lower bound of the associated range is at the same index as the string.
since
Android 1.0

        if (limits.length != formats.length) {
            throw new IllegalArgumentException();
        }
        choiceLimits = limits;
        choiceFormats = formats;
    
private intskipWhitespace(java.lang.String string, int index)

        int length = string.length();
        while (index < length && Character.isWhitespace(string.charAt(index))) {
            index++;
        }
        return index;
    
public java.lang.StringtoPattern()
Returns the pattern of this {@code ChoiceFormat} which specifies the ranges and their associated strings.

return
the pattern.
since
Android 1.0

        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < choiceLimits.length; i++) {
            if (i != 0) {
                buffer.append('|");
            }
            String previous = String.valueOf(previousDouble(choiceLimits[i]));
            String limit = String.valueOf(choiceLimits[i]);
            if (previous.length() < limit.length()) {
                buffer.append(previous);
                buffer.append('<");
            } else {
                buffer.append(limit);
                buffer.append('#");
            }
            boolean quote = (choiceFormats[i].indexOf('|") != -1);
            if (quote) {
                buffer.append('\'");
            }
            buffer.append(choiceFormats[i]);
            if (quote) {
                buffer.append('\'");
            }
        }
        return buffer.toString();