【问题标题】:Java BigDecimal formattingJava BigDecimal 格式化
【发布时间】:2017-01-03 00:07:07
【问题描述】:

我有一个带有 BigDecimal 字段的课程。我把这个对象放到 JSP(Spring MVC)中。而且我需要在十进制中显示不为零的 BigDecimal 字段(20.00 像 20),这就是为什么我的 getter 方法看起来像

public BigDecimal getValue() {
    return value.stripTrailingZeros();
}

我有下一个结果:

20.50 = 20.5;
13.25 = 13.25;
30.00 = 3E+1.

如何将 3E+1 更改为 30 ?我可以用 Java 或 JSTL 格式化吗?

【问题讨论】:

    标签: java jstl bigdecimal


    【解决方案1】:

    我找到了一个简单的解决方案。它不需要在 getter 方法中做 stripTrailingZeros() 。只是

    public BigDecimal getValue() {
        return value;
    }
    

    并在 JSP 上

    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    
    <fmt:formatNumber value="${object.value}" minFractionDigits="0"/>
    

    【讨论】:

      【解决方案2】:

      我认为你可以在返回的 bigdecimal 上使用 toPlainString()。

      简单的测试程序:

          BigDecimal[] bds={new BigDecimal("1.0"),new BigDecimal("20.50"), 
                    new BigDecimal("13.25"), 
                    new BigDecimal("30.0"),
                    new BigDecimal("30.01000"), new BigDecimal("0.0000")
          };
          for (BigDecimal bd: bds)
              System.out.println(bd+"==>"+bd.stripTrailingZeros().toPlainString());
      

      返回:

        1.0==>1
        20.50==>20.5
        13.25==>13.25
        30.0==>30
        30.01000==>30.01
        0.0000==>0.0000
      

      我知道只有一种边界情况不起作用..这是 0 的所有变体。

        0.0 => 0.0
        0.00 => 0.00
      

      我相信这篇堆栈溢出文章已经涵盖了这一点:Why does new BigDecimal("0.0").stripTrailingZeros() have a scale of 1? 根据文章,这已在 java 8 中得到纠正(但我还没有测试过)。

      在这种情况下,您可以通过执行 compareTo(BigDecimal.ZERO)==0 并使用 BigDecimal.ZERO 来摆脱它。

      BigDecimal[] bds={new BigDecimal("1.0"),
                        new BigDecimal("20.50"),
                        new BigDecimal("13.25"),
                        new BigDecimal("30.0"),
                        new BigDecimal("30.01000"), 
                        new BigDecimal("0.0000")
          };
          for (BigDecimal bd: bds){
              if (bd.compareTo(BigDecimal.ZERO) == 0){
                  System.out.println(bd+"=>"+BigDecimal.ZERO);
              }
              else {
                  System.out.println(bd+"==>"+bd.stripTrailingZeros().toPlainString());
              }
      

      返回:

        1.0==>1
        20.50==>20.5
        13.25==>13.25
        30.0==>30
        30.01000==>30.01
        0.0000=>0
      

      【讨论】:

        【解决方案3】:

        如果您可以控制从BigDecimalString 的格式化方法(框架正在显示从BigDecimal.toString() 返回的字符串),您可以使用NumberFormat 更好地控制显示的字符串。

        根据Spring documentation,您可以为该作业实现自定义格式化程序。

        我建议你覆盖默认的NumberFormatter 并覆盖print 方法,如下所示:

        public class NoZeroesBigDecimalFormatter extends org.springframework.format.number.NumberFormatter{
            @Override
            public String print(Number number, Locale locale) {
                NumberFormat nf = NumberFormat.getInstance();
                nf.setMaximumFractionDigits(5); //whatever value is your maximum displayed digits
                return nf.format(value);
            }
        }
        

        然后,看看如何将该格式化程序绑定到您的字段。

        【讨论】:

        • 感谢您的回答,但我不想覆盖序列化。我想知道是否有一些方法可以在服务器或 UI 上对其进行格式化。
        • @AlexSmith 这不是覆盖序列化,而是覆盖框架上的转换策略。
        猜你喜欢
        • 2017-06-25
        • 2012-10-02
        • 2013-06-21
        • 1970-01-01
        • 2011-03-24
        • 2013-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多