数据比较时String未转成BigDecimal的坑

如果价格的字段是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的长度

@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 √
*/

你可能感兴趣的:(java)