📄 choiceformat.java
字号:
/** * Set the choices to be used in formatting. * @param limits contains the top value that you want * parsed with that format,and should be in ascending sorted order. When * formatting X, the choice will be the i, where * limit[i] <= X < limit[i+1]. * If the limit array is not in ascending order, the results of formatting * will be incorrect. * @param formats are the formats you want to use for each limit. * They can be either Format objects or Strings. * When formatting with object Y, * if the object is a NumberFormat, then ((NumberFormat) Y).format(X) * is called. Otherwise Y.toString() is called. */ public void setChoices(double[] limits, String formats[]) { if (limits.length != formats.length) { throw new IllegalArgumentException( "Array and limit arrays must be of the same length."); } choiceLimits = limits; choiceFormats = formats; } /** * Get the limits passed in the constructor. * @return the limits. */ public double[] getLimits() { return choiceLimits; } /** * Get the formats passed in the constructor. * @return the formats. */ public Object[] getFormats() { return choiceFormats; } // Overrides /** * Specialization of format. This method really calls * <code>format(double, StringBuffer, FieldPosition)</code> * thus the range of longs that are supported is only equal to * the range that can be stored by double. This will never be * a practical limitation. */ public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition status) { return format((double)number, toAppendTo, status); } /** * Returns pattern with formatted double. * @param number number to be formatted & substituted. * @param toAppendTo where text is appended. * @param status ignore no useful status is returned. */ public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition status) { // find the number int i; for (i = 0; i < choiceLimits.length; ++i) { if (!(number >= choiceLimits[i])) { // same as number < choiceLimits, except catchs NaN break; } } --i; if (i < 0) i = 0; // return either a formatted number, or a string return toAppendTo.append(choiceFormats[i]); } /** * Parses a Number from the input text. * @param text the source text. * @param status an input-output parameter. On input, the * status.index field indicates the first character of the * source text that should be parsed. On exit, if no error * occured, status.index is set to the first unparsed character * in the source text. On exit, if an error did occur, * status.index is unchanged and status.errorIndex is set to the * first index of the character that caused the parse to fail. * @return A Number representing the value of the number parsed. */ public Number parse(String text, ParsePosition status) { // find the best number (defined as the one with the longest parse) int start = status.index; int furthest = start; double bestNumber = Double.NaN; double tempNumber = 0.0; for (int i = 0; i < choiceFormats.length; ++i) { String tempString = choiceFormats[i]; if (text.regionMatches(start, tempString, 0, tempString.length())) { status.index = start + tempString.length(); tempNumber = choiceLimits[i]; if (status.index > furthest) { furthest = status.index; bestNumber = tempNumber; if (furthest == text.length()) break; } } } status.index = furthest; if (status.index == start) { status.errorIndex = furthest; } return new Double(bestNumber); } /** * Finds the least double greater than d. * If NaN, returns same value. * <p>Used to make half-open intervals. * @see #previousDouble */ public static final double nextDouble (double d) { return nextDouble(d,true); } /** * Finds the greatest double less than d. * If NaN, returns same value. * @see #nextDouble */ public static final double previousDouble (double d) { return nextDouble(d,false); } /** * Overrides Cloneable */ public Object clone() { ChoiceFormat other = (ChoiceFormat) super.clone(); // for primitives or immutables, shallow clone is enough other.choiceLimits = (double[]) choiceLimits.clone(); other.choiceFormats = (String[]) choiceFormats.clone(); return other; } /** * Generates a hash code for the message format object. */ public int hashCode() { int result = choiceLimits.length; if (choiceFormats.length > 0) { // enough for reasonable distribution result ^= choiceFormats[choiceFormats.length-1].hashCode(); } return result; } /** * Equality comparision between two */ public boolean equals(Object obj) { if (obj == null) return false; if (this == obj) // quick check return true; if (getClass() != obj.getClass()) return false; ChoiceFormat other = (ChoiceFormat) obj; return (Utility.arrayEquals(choiceLimits,other.choiceLimits) && Utility.arrayEquals(choiceFormats,other.choiceFormats)); } /** * After reading an object from the input stream, do a simple verification * to maintain class invariants. * @throws InvalidObjectException if the objects read from the stream is invalid. */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); if (choiceLimits.length != choiceFormats.length) { throw new InvalidObjectException( "limits and format arrays of different length."); } } // ===============privates=========================== /** * A list of lower bounds for the choices. The formatter will return * <code>choiceFormats[i]</code> if the number being formatted is greater than or equal to * <code>choiceLimits[i]</code> and less than <code>choiceLimits[i+1]</code>. * @serial */ private double[] choiceLimits; /** * A list of choice strings. The formatter will return * <code>choiceFormats[i]</code> if the number being formatted is greater than or equal to * <code>choiceLimits[i]</code> and less than <code>choiceLimits[i+1]</code>. * @serial */ private String[] choiceFormats; /* static final long SIGN = 0x8000000000000000L; static final long EXPONENT = 0x7FF0000000000000L; static final long SIGNIFICAND = 0x000FFFFFFFFFFFFFL; private static double nextDouble (double d, boolean positive) { if (Double.isNaN(d) || Double.isInfinite(d)) { return d; } long bits = Double.doubleToLongBits(d); long significand = bits & SIGNIFICAND; if (bits < 0) { significand |= (SIGN | EXPONENT); } long exponent = bits & EXPONENT; if (positive) { significand += 1; // FIXME fix overflow & underflow } else { significand -= 1; // FIXME fix overflow & underflow } bits = exponent | (significand & ~EXPONENT); return Double.longBitsToDouble(bits); } */ static final long SIGN = 0x8000000000000000L; static final long EXPONENT = 0x7FF0000000000000L; static final long POSITIVEINFINITY = 0x7FF0000000000000L; /** * Finds the least double greater than d (if positive == true), * or the greatest double less than d (if positive == false). * If NaN, returns same value. * * Does not affect floating-point flags, * provided these member functions do not: * Double.longBitsToDouble(long) * Double.doubleToLongBits(double) * Double.isNaN(double) */ public static double nextDouble (double d, boolean positive) { /* filter out NaN's */ if (Double.isNaN(d)) { return d; } /* zero's are also a special case */ if (d == 0.0) { double smallestPositiveDouble = Double.longBitsToDouble(1L); if (positive) { return smallestPositiveDouble; } else { return -smallestPositiveDouble; } } /* if entering here, d is a nonzero value */ /* hold all bits in a long for later use */ long bits = Double.doubleToLongBits(d); /* strip off the sign bit */ long magnitude = bits & ~SIGN; /* if next double away from zero, increase magnitude */ if ((bits > 0) == positive) { if (magnitude != POSITIVEINFINITY) { magnitude += 1; } } /* else decrease magnitude */ else { magnitude -= 1; } /* restore sign bit and return */ long signbit = bits & SIGN; return Double.longBitsToDouble (magnitude | signbit); } private static double[] doubleArraySize(double[] array) { int oldSize = array.length; double[] newArray = new double[oldSize * 2]; System.arraycopy(array, 0, newArray, 0, oldSize); return newArray; } private String[] doubleArraySize(String[] array) { int oldSize = array.length; String[] newArray = new String[oldSize * 2]; System.arraycopy(array, 0, newArray, 0, oldSize); return newArray; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -