我认为要接受所有八种数值类型(原始和对象),该方法必须采用字符串参数。调用者必须记住通过这个习语将值转换为字符串:
""+value
此外,如果值不是整数(int、Integer、long、Long)而是浮点表示(float、double、Float、@987654329 @),该方法还必须带一个参数 epsilon 以容忍由于表示而导致的不精确性。
所以这是一个实现想法(现在我忽略 NaN 和 double 的正负零的情况——如果需要真正可靠的实现,可以添加这些)
private static boolean equalsNumerically(String n1String
, String n2String
, double epsilon) {
try {
Long n1Long = new Long(n1String);
Long n2Long = new Long(n2String);
return n1Long.equals(n2Long);
} catch (NumberFormatException e) {
/*
* If either one of the number is not an integer, try comparing
* the two as Double
*/
try {
Double n1Double = new Double(n1String);
Double n2Double = new Double(n2String);
double delta = ( n1Double - n2Double) / n2Double;
if (delta<epsilon) {
return true;
} else {
return false;
}
} catch (NumberFormatException e2) {
return false;
}
}
}
测试代码
int primitiveInt = 1;
long primitiveLong = 1L;
float primitiveFloat = 0.999999F;
double primitiveDouble = 0.999999D;
Integer objectInt = new Integer(1);
Long objectLong = new Long(1);
Float objectFloat = new Float(0.999999);
Double objectDouble = new Double(0.999999);
final double epsilon = 1E-3;
Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+primitiveLong, 0));
System.out.format("Test passed: "
+ "Assert.assertTrue(equalsNumerically(\"\"+primitiveInt"
+ ", \"\"+primitiveLong, 0): %s %s %s%n"
, primitiveInt, primitiveLong, epsilon);
Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+primitiveLong, epsilon));
System.out.format("Test passed: "
+ "Assert.assertTrue(equalsNumerically(\"\"+primitiveInt"
+ ", \"\"+primitiveLong, epsilon)): %s %s %s%n"
, primitiveInt, primitiveLong, epsilon);
Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+primitiveFloat, epsilon));
System.out.format("Test passed: "
+ "Assert.assertTrue(equalsNumerically(\"\"+primitiveInt"
+ ", \"\"+primitiveFloat, 0): %s %s %s%n"
, primitiveInt, primitiveFloat, epsilon);
Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+primitiveDouble, epsilon));
System.out.format("Test passed: "
+ "Assert.assertTrue(equalsNumerically(\"\"+primitiveInt"
+ ", \"\"+primitiveDouble, epsilon): %s %s %s%n"
, primitiveInt, primitiveDouble, epsilon);
Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+objectInt, 0));
System.out.format("Test passed: "
+ "Assert.assertTrue(equalsNumerically(\"\"+primitiveInt"
+ ", \"\"+objectInt, 0): %s %s %s%n"
, primitiveInt, objectInt, epsilon);
Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+objectLong, 0));
System.out.format("Test passed: "
+ "Assert.assertTrue(equalsNumerically(\"\"+objectLong"
+ ", \"\"+objectLong, 0): %s %s %s%n"
, primitiveInt, primitiveLong, epsilon);
Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+objectFloat, epsilon));
System.out.format("Test passed: "
+ "Assert.assertTrue(equalsNumerically(\"\"+primitiveInt"
+ ", \"\"+objectFloat, epsilon)): %s %s %s%n"
, primitiveInt, objectFloat, epsilon);
Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+objectDouble, epsilon));
System.out.format("Test passed: "
+ "Assert.assertTrue(equalsNumerically(\"\"+primitiveInt"
+ ", \"\"+objectDouble, 0): %s %s %s%n"
, primitiveInt, objectDouble, epsilon);
测试输出
Test passed: Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+primitiveLong, 0): 1 1 0.001
Test passed: Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+primitiveLong, epsilon)): 1 1 0.001
Test passed: Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+primitiveFloat, 0): 1 0.999999 0.001
Test passed: Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+primitiveDouble, epsilon): 1 0.999999 0.001
Test passed: Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+objectInt, 0): 1 1 0.001
Test passed: Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+objectLong, 0): 1 1 0.001
Test passed: Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+objectFloat, epsilon)): 1 0.999999 0.001
Test passed: Assert.assertTrue(equalsNumerically(""+primitiveInt, ""+objectDouble, 0): 1 0.999999 0.001