相关疑难解决方法(0)

BigDecimal等于()与compareTo()

考虑简单的测试类:

import java.math.BigDecimal;

/**
 * @author The Elite Gentleman
 *
 */
public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        BigDecimal x = new BigDecimal("1");
        BigDecimal y = new BigDecimal("1.00");
        System.out.println(x.equals(y));
        System.out.println(x.compareTo(y) == 0 ? "true": "false");
    }

}
Run Code Online (Sandbox Code Playgroud)

你可以(有意识地)说它x等于y(不是对象引用),但是当你运行程序时,以下结果显示:

false
true
Run Code Online (Sandbox Code Playgroud)

问:什么是之间的区别compareTo(),并equals()BigDecimalcompareTo可以确定x等于y

PS:我看到BigDecimal在inflate()方法上有一个equals()方法.inflate()实际上做了什么?

java equals bigdecimal compareto

141
推荐指数
1
解决办法
11万
查看次数

为什么BigDecimal("5.50")不等于BigDecimal("5.5")以及如何解决这个问题?

实际上,我找到了可能的解决方案

//returns true
new BigDecimal("5.50").doubleValue() == new BigDecimal("5.5").doubleValue()
Run Code Online (Sandbox Code Playgroud)

当然,它可以通过类似的Math.abs (v1 - v2) < EPS方式进行改进,使比较更加健壮,但问题是这种技术是否可以接受或是否有更好的解决方案?

如果有人知道为什么java设计师决定以这种方式实现BigDecimal的平等,那么阅读它会很有趣.

java equals bigdecimal

49
推荐指数
3
解决办法
3万
查看次数

比较与equals一致意味着什么?如果我的班级不遵循这个原则,可能会发生什么?

从TreeMap的JavaDoc:

请注意,如果此有序映射要正确实现Map接口,则由有序映射维护的排序(无论是否提供显式比较器)必须与equals一致.(请参阅Comparable或Comparator以获得与equals一致的精确定义.)这是因为Map接口是根据equals操作定义的,但是map使用compareTo(或compare)方法执行所有键比较,因此有两个键从排序地图的角度来看,通过这种方法被视为相等的是相等的.即使排序与equals不一致,也可以很好地定义有序映射的行为.它只是不遵守Map接口的一般合同.

有人可以给出一个具体的例子来说明如果排序与equals不一致可能会出现的问题吗?举例来说,用户定义的类具有自然顺序,即它实现了Comparable.JDK中的所有内部类都保持这个不变量吗?

java comparison equals comparable comparator

17
推荐指数
4
解决办法
1万
查看次数

如何以与比例无关的方式检查BigDecimal是否在Set或Map中?

BigDecimal的equals()方法也比较比例,所以

new BigDecimal("0.2").equals(new BigDecimal("0.20")) // false
Run Code Online (Sandbox Code Playgroud)

有人质疑它为何如此行事.

现在,假设我有一个Set<BigDecimal>,如何检查0.2是否在该集合中,是否独立?

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

java bigdecimal

10
推荐指数
1
解决办法
1844
查看次数

如果仅更改了比例,则不会调用BigDecimal值的ValueChangeListener

我有一个JSF 2.2应用程序,用户必须输入BigDecimal<h:inputText>.对于这样的输入字段,a valueChangeListener被配置为在输入变化时被调用.这是XHTML代码:

<h:form id="theForm">
  <h:inputText id="bd" value="#{bean.bd}"
               valueChangeListener="#{bean.bdChangedListener()}"/>
  <h:commandButton id="submit" value="Submit" />
</h:form>
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,这样做很好.bdChangedListener()当值改变并按下提交按钮时,将调用该方法.该值已正确提交给模型.

但是,如果我进入1.1并改变它1.10,新的值被提交到模型,但valueChangeListener从来没有所谓!Debuging表明,其原因在于javax.faces.component.UIInput#compareValues().这种方法的JavaDoc 说:

如果新值与先前值不同,则返回true.首先通过将值传递给参数previous之前的equals方法来比较这两个值.如果该方法返回true,则返回true.如果该方法返回false,并且两个参数都实现java.lang.Comparable,则通过将值传递给参数previous之前的compareTo方法来比较这两个值.如果此方法返回0,则返回true,否则返回false.

所以在我看来,这是故意的.但为什么?

用户输入已更改,并且存在应用程序,其中a的比例BigDecimal是相关的.所以JSF不应该忽略改变的输入,而是通知我!它使用新值更新模型,为什么它会跳过valueChangeListener-method?

我怎样才能避免这种行为并以干净的方式得到通知?(我知道我可以挂进制定者,但这不是我所谓的干净方式!)

有任何想法吗?

进一步阅读和评论

除了上面我想提到的,我已经读过像BigDecimal equals()和compareTo()这样的问题.我确实理解为什么BigDecimal equals()compareTo()他们的行为一样,我说它是正确的.BigDecimal的行为不是问题,UIInput.compareValues()而是问题.

此外,转换器(如评论或已删除的答案中所示)将无法保存我的一天.用户输入已正确转换,我需要BidDecimal,包括我的应用程序中的确切比例.任何返回BigDecimal的转换器都不会改变观察到的行为.

围绕BigDecimal的包装类可能会解决我的问题,但不是我认为的干净解决方案.我真的想知道为什么UIInput的行为方式.

jsf

10
推荐指数
1
解决办法
287
查看次数

AssertJ:如何使用compareTo和extracting()来断言BigDecimals

我将 AssertJextracting()方法与 Java8 lambda 一起使用,并将一些字段映射到 BigDecimal,然后断言结果数组。但我需要使用 BigDecimalcompareTo()和不使用BigDecimal 进行比较equals()(因此。我怎样才能做到这一点?

例子:

Actual actual = performTest();

Assertions.assertThat(actual)
  .extracting(
    Actual::getName,   // returns String
    Actual::getValue  // returns BigDecimal
  )
  .containsExactly(
    "abc",                 // ok, String equals comparison
    new BigDecimal("1.1")  // NOT OK, equals comparison, but I need compareTo comparison
  );
Run Code Online (Sandbox Code Playgroud)

编辑:我正在寻找一种流畅的方法来执行此操作,因为我当然可以将其拆分为多个不同的断言并以这种方式进行比较,或者将所有内容放入一个巨大的Condition.

java assertj

3
推荐指数
1
解决办法
5642
查看次数