如果价格的字段是String,要转换成BigDecimal等数字再比较,用String比较会出现奇怪的错误。
这句话看起来很多余,但是实际写代码的时候确是很容易忽略。
比如价格这个字段封装在对象里,而你只是a.getPrice().compareTo(b.getPrice())
。
CompareTo的String与BigDecimal对比
这里的场景是:假设市场价格mktPx >= 我的目标价格targetPx,我就卖出
但String的CompareTo是把String的值,也就是char []
数组,按index比较两个对象对应index的char值的大小
6.555和6.5550前4位都相等,方法直接返回len1 - len2
,mktPx的长度<targetPx,所以比较结果-1显示这两个价格不相等
@Test
public void testCompareTo() {
String mktPx = "6.555";
String targetPx = "6.5550";
System.out.println("String: " + mktPx.compareTo(targetPx));
BigDecimal mktPx1 = new BigDecimal(mktPx);
BigDecimal targetPx1 = new BigDecimal(targetPx);
System.out.println("BigDecimal: " + mktPx1.compareTo(targetPx1));
}
/*
String: -1 // 价格不相等 ×
BigDecimal: 0 // 价格相等 √
*/
String的CompareTo
// java.lang.String#compareTo
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
其他需要注意转换的点
Comparator
自己实现Comparator @Override
compare()方法时,遇到String字段要记得先转换再比较
@Test
public void testStringComparator() {
List<String> sortedList = new ArrayList<>();
sortedList.add("20");
sortedList.add("100");
// 默认升序排序
sortedList.sort((s1, s2) -> {
return Integer.compare(s1.compareTo(s2), 0);
});
System.out.println("String: " + sortedList.get(0));
// 默认升序排序
sortedList.sort((s1, s2) -> {
BigDecimal price1 = new BigDecimal(s1);
BigDecimal price2 = new BigDecimal(s2);
return Integer.compare(price1.compareTo(price2), 0);
});
System.out.println("BigDecimal: " + sortedList.get(0));
}
/*
String: 100 // 认为(s2[0] == 1) < (s1[0] == 2) ×
BigDecimal: 20 // 数字比较 20 < 100 √
*/