ChoiceFormatpublic 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.
|
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.
setChoices(limits, formats);
| public ChoiceFormat(String template)Constructs a new {@code ChoiceFormat} with the strings and limits parsed
from the specified pattern.
applyPattern(template);
|
Methods Summary |
---|
public void | applyPattern(java.lang.String template)Parses the pattern to determine new strings and ranges for this
{@code ChoiceFormat}.
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.Object | clone()Returns a new instance of {@code ChoiceFormat} with the same ranges and
strings as this {@code ChoiceFormat}.
ChoiceFormat clone = (ChoiceFormat) super.clone();
clone.choiceLimits = choiceLimits.clone();
clone.choiceFormats = choiceFormats.clone();
return clone;
| public boolean | equals(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.
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.StringBuffer | format(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.
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.StringBuffer | format(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.
return format((double) value, buffer, field);
| public java.lang.Object[] | getFormats()Returns the strings associated with the ranges of this {@code
ChoiceFormat}.
return choiceFormats;
| public double[] | getLimits()Returns the limits of this {@code ChoiceFormat}.
return choiceLimits;
| public int | hashCode()Returns an integer hash code for the receiver. Objects which are equal
return the same value for this method.
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 double | nextDouble(double value)Returns the double value which is closest to the specified double but
larger.
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 double | nextDouble(double value, boolean increment)Returns the double value which is closest to the specified double but
either larger or smaller as specified.
return increment ? nextDouble(value) : previousDouble(value);
| public java.lang.Number | parse(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.
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 double | previousDouble(double value)Returns the double value which is closest to the specified double but
smaller.
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 void | setChoices(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.
if (limits.length != formats.length) {
throw new IllegalArgumentException();
}
choiceLimits = limits;
choiceFormats = formats;
| private int | skipWhitespace(java.lang.String string, int index)
int length = string.length();
while (index < length && Character.isWhitespace(string.charAt(index))) {
index++;
}
return index;
| public java.lang.String | toPattern()Returns the pattern of this {@code ChoiceFormat} which specifies the
ranges and their associated strings.
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();
|
|