📄 mathtool.java
字号:
}
// --------------- public type conversion methods ---------
/**
* Converts an object with a numeric value into an Integer
* Valid formats are {@link Number} or a {@link String}
* representation of a number
*
* @param num the number to be converted
* @return a {@link Integer} representation of the number
* or <code>null</code> if it's invalid
*/
public Integer toInteger(Object num)
{
Number n = toNumber(num);
if (n == null)
{
return null;
}
return new Integer(n.intValue());
}
/**
* Converts an object with a numeric value into a Double
* Valid formats are {@link Number} or a {@link String}
* representation of a number
*
* @param num the number to be converted
* @return a {@link Double} representation of the number
* or <code>null</code> if it's invalid
*/
public Double toDouble(Object num)
{
Number n = toNumber(num);
if (n == null)
{
return null;
}
return new Double(n.doubleValue());
}
/**
* Converts an object with a numeric value into a Number
* Valid formats are {@link Number} or a {@link String}
* representation of a number. Note that this does not
* handle localized number formats. Use the {@link NumberTool}
* to handle such conversions.
*
* @param num the number to be converted
* @return a {@link Number} representation of the number
* or <code>null</code> if it's invalid
*/
public Number toNumber(Object num)
{
if (num == null)
{
return null;
}
if (num instanceof Number)
{
return (Number)num;
}
try
{
return parseNumber(String.valueOf(num));
}
catch (NumberFormatException nfe)
{
return null;
}
}
// --------------------------- protected methods ------------------
/**
* @see #matchType(Number,Number,double)
*/
protected Number matchType(Number in, double out)
{
return matchType(in, null, out);
}
/**
* Takes the original argument(s) and returns the resulting value as
* an instance of the best matching type (Integer, Long, or Double).
* If either an argument or the result is not an integer (i.e. has no
* decimal when rendered) the result will be returned as a Double.
* If not and the result is < -2147483648 or > 2147483647, then a
* Long will be returned. Otherwise, an Integer will be returned.
*/
protected Number matchType(Number in1, Number in2, double out)
{
//NOTE: if we just checked class types, we could miss custom
// extensions of java.lang.Number, and if we only checked
// the mathematical value, $math.div('3.0', 1) would render
// as '3'. To get the expected result, we check what we're
// concerned about: the rendered string.
// first check if the result is a whole number
boolean isWhole = (Math.rint(out) == out);
if (isWhole)
{
// assume that 1st arg is not null,
// check for floating points
String in = in1.toString();
isWhole = (in.indexOf('.') < 0);
// if we don't have a decimal yet but do have a second arg
if (isWhole && in2 != null)
{
in = in2.toString();
isWhole = (in.indexOf('.') < 0);
}
}
if (!isWhole)
{
return new Double(out);
}
else if (out > Integer.MAX_VALUE || out < Integer.MIN_VALUE)
{
return new Long((long)out);
}
else
{
return new Integer((int)out);
}
}
/**
* Converts an object into a {@link Number} (if it can)
* This is used as the base for all numeric parsing methods. So,
* sub-classes can override to allow for customized number parsing.
* (e.g. for i18n, fractions, compound numbers, bigger numbers, etc.)
*
* @param value the string to be parsed
* @return the value as a {@link Number}
*/
protected Number parseNumber(String value) throws NumberFormatException
{
// check for the floating point
if (value.indexOf('.') < 0)
{
// check for large numbers
long i = new Long(value).longValue();
if (i > Integer.MAX_VALUE || i < Integer.MIN_VALUE)
{
return new Long(i);
}
else
{
return new Integer((int)i);
}
}
else
{
return new Double(value);
}
}
// ------------------------- Aggregation methods ------------------
/**
* Get the sum of the values from a list
*
* @param collection A collection containing Java beans
* @param field A Java Bean field for the objects in <i>collection</i> that
* will return a number.
* @return The sum of the values in <i>collection</i>.
*/
public Number getTotal(Collection collection, String field)
{
if (collection == null || field == null)
{
return null;
}
try
{
double result = 0;
// hold the first number and use it to match return type
Number first = null;
for (Iterator i = collection.iterator(); i.hasNext();)
{
Object property = PropertyUtils.getProperty(i.next(), field);
Number value = toNumber(property);
if (first == null)
{
first = value;
}
result += value.doubleValue();
}
return matchType(first, result);
}
catch (Exception e)
{
//FIXME? Log this?
return null;
}
}
/**
* Get the average of the values from a list
*
* @param collection A collection containing Java beans
* @param field A Java Bean field for the objects in <i>collection</i> that
* will return a number.
* @return The average of the values in <i>collection</i>.
*/
public Number getAverage(Collection collection, String field)
{
Number result = getTotal(collection, field);
if (result == null)
{
return null;
}
double avg = result.doubleValue() / collection.size();
return matchType(result, avg);
}
/**
* Get the sum of the values from a list
*
* @param array An array containing Java beans
* @param field A Java Bean field for the objects in <i>array</i> that
* will return a number.
* @return The sum of the values in <i>array</i>.
*/
public Number getTotal(Object[] array, String field)
{
return getTotal(Arrays.asList(array), field);
}
/**
* Get the sum of the values from a list
*
* @param array A collection containing Java beans
* @param field A Java Bean field for the objects in <i>array</i> that
* will return a number.
* @return The sum of the values in <i>array</i>.
*/
public Number getAverage(Object[] array, String field)
{
return getAverage(Arrays.asList(array), field);
}
/**
* Get the sum of the values
*
* @param collection A collection containing numeric values
* @return The sum of the values in <i>collection</i>.
*/
public Number getTotal(Collection collection)
{
if (collection == null)
{
return null;
}
double result = 0;
// grab the first number and use it to match return type
Number first = null;
for (Iterator i = collection.iterator(); i.hasNext();)
{
Number value = toNumber(i.next());
if (value == null)
{
//FIXME? or should we ignore this and keep adding?
return null;
}
if (first == null)
{
first = value;
}
result += value.doubleValue();
}
return matchType(first, result);
}
/**
* Get the average of the values
*
* @param collection A collection containing number values
* @return The average of the values in <i>collection</i>.
*/
public Number getAverage(Collection collection)
{
Number result = getTotal(collection);
if (result == null)
{
return null;
}
double avg = result.doubleValue() / collection.size();
return matchType(result, avg);
}
/**
* Get the sum of the values
*
* @param array An array containing number values
* @return The sum of the values in <i>array</i>.
*/
public Number getTotal(Object[] array)
{
return getTotal(Arrays.asList(array));
}
/**
* Get the average of the values
*
* @param array An array containing number values
* @return The sum of the values in <i>array</i>.
*/
public Number getAverage(Object[] array)
{
return getAverage(Arrays.asList(array));
}
/**
* Get the sum of the values
*
* @param values The list of double values to add up.
* @return The sum of the arrays
*/
public Number getTotal(double[] values)
{
if (values == null)
{
return null;
}
double result = 0;
for (int i = 0; i < values.length; i++)
{
result += values[i];
}
return new Double(result);
}
/**
* Get the average of the values in an array of double values
*
* @param values The list of double values
* @return The average of the array of values
*/
public Number getAverage(double[] values)
{
Number total = getTotal(values);
if (total == null)
{
return null;
}
return new Double(total.doubleValue() / values.length);
}
/**
* Get the sum of the values
*
* @param values The list of long values to add up.
* @return The sum of the arrays
*/
public Number getTotal(long[] values)
{
if (values == null)
{
return null;
}
long result = 0;
for (int i = 0; i < values.length; i++)
{
result += values[i];
}
return new Long(result);
}
/**
* Get the average of the values in an array of long values
*
* @param values The list of long values
* @return The average of the array of values
*/
public Number getAverage(long[] values)
{
Number total = getTotal(values);
if (total == null)
{
return null;
}
double avg = total.doubleValue() / values.length;
return matchType(total, avg);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -