How do I check if a BigDecimal is in a Set or Map in a scale independent way?

心不动则不痛 提交于 2019-12-01 14:27:56

问题


BigDecimal's equals() method compares scale too, so

new BigDecimal("0.2").equals(new BigDecimal("0.20")) // false

It's contested why it behaves like that.

Now, suppose I have a Set<BigDecimal>, how do I check if 0.2 is in that Set, scale independent?

Set<BigDecimal> set = new HashSet<>();
set.add(new BigDecimal("0.20"));
...
if (set.contains(new BigDecimal("0.2")) { // Returns false, but should return true
    ...
}

回答1:


contains() will work as you want it to if you switch your HashSet to a TreeSet.

It is different from most sets as it will decide equality based on the compareTo() method as opposed to equals() and hashCode():

a TreeSet instance performs all element comparisons using its compareTo (or compare) method

And since BigDecimal.compareTo() compares without regard to scale, that's exactly what you want here.

Alternatively you could ensure that all elements in the Set are of the same, minimal scale, by always using stripTrailingZeros (both on add() and on contains()):

set.add(new BigDecimal("0.20").stripTrailingZeros());
...
if (set.contains(new BigDecimal("0.2").stripTrailingZeros()) {
  ...
}



回答2:


HashSet#contains method can't serve your requirement, it implicitly call equals method. You should iterate over Set and use compareTo method. If value is found than set a flag.

    Set<BigDecimal> set = new HashSet<>();
    set.add(new BigDecimal("0.20"));
    boolean found=false;
    for (BigDecimal bigDecimal : set) {
        if(bigDecimal.compareTo(new BigDecimal("0.2"))==0){
            System.out.println("Value is contain");
            found=true;
            break;
        }
    }
    if(found)// Use this flag for codition.



回答3:


Use the compareTo method of BigDecimal.

BigDecimal("0.200").compareTo(new BigDecimal("0.2")) == 0; // Means they are equal.

From the JavaDoc

Compares this BigDecimal with the specified BigDecimal. Two BigDecimal objects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by this method. This method is provided in preference to individual methods for each of the six boolean comparison operators (<, ==, >, >=, !=, <=). The suggested idiom for performing these comparisons is: (x.compareTo(y) <op> 0), where <op> is one of the six comparison operators.



来源:https://stackoverflow.com/questions/20091723/how-do-i-check-if-a-bigdecimal-is-in-a-set-or-map-in-a-scale-independent-way

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!