Java SE 随机数生成器 Random、DecimalFormat 与 NumberFormat 数值格式化

目录

DecimalFormat 与 NumberFormat 数值格式化

数值格式化概述

数字格式化演示

随机数生成器 Random

Random 性能问题

ThreadLocalRandom

SecureRandom


DecimalFormat 与 NumberFormat 数值格式化

数值格式化概述

1、NumberFormat 可以格式化和解析任何区域设置的数字,代码可以完全独立于小数点,千位分隔符的区域设置约定,甚至是使用的特定十进制数字,或者数字格式是否为十进制。

2、DecimalFormat 是 NumberFormat 十进制数字格式的具体子类,它具有多种功能,旨在解析和格式化任何语言环境中的数字,包括支持西方,阿拉伯语和印度语数字,它还支持不同类型的数字,包括整数(123),定点数(123.4),科学记数法(1.23E4),百分比(12%)和货币金额($123)。

3、NumberFormat 和 DecimalFormat 是线程不安全的,建议为每个线程创建单独的格式实例,如果多个线程同时访问格式,则必须在外部进行同步。

NumberFormat 实例化

NumberFormat numberFormat = NumberFormat.getInstance(); //返回当前默认语言环境的通用数值格式。
NumberFormat numberFormat = NumberFormat.getNumberInstance(); //返回当前默认语言环境的通用数值格式。 
NumberFormat numberFormat = NumberFormat.getInstance(Locale.CHINA); //返回指定语言环境的通用数值格式。
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.CHINA); //返回指定语言环境的通用数值格式。 
NumberFormat numberFormat = NumberFormat.getIntegerInstance(); //获取整数格式
NumberFormat numberFormat = NumberFormat.getCurrencyInstance() //获取货币格式
NumberFormat numberFormat = NumberFormat.getPercentInstance() //获取显示百分比的格式

DecimalFormat 实例化

DecimalFormat decimalFormat = (DecimalFormat) numberFormat; //强制转换
DecimalFormat decimalFormat = new DecimalFormat();
DecimalFormat decimalFormat = new DecimalFormat("0000.000");

DecimalFormat 常用方法

decimalFormat.setMinimumIntegerDigits(int); //设置整数部分所允许的最小位数,不足的首部用补齐。 decimalFormat.setMaximumIntegerDigits(int); //设置整数部分所允许的最大位数。

decimalFormat.setMinimumFractionDigits(int); //设置最少小数点位数,不足的位数末尾以 0 补齐。 decimalFormat.setMaximumFractionDigits(int); //设置最多保留小数位数。

String format(double number)  //格式化数字
String format(long number)     //格式化数字

String format (Object obj) //格式化数字,注意必须是 Integer、Long、Flout、Double、BigDecimal、BigInteger等等数值类型,如果是 String ,则会抛异常。

decimalFormat.format("0.089") ; // 像这样直接抛出异常:java.lang.IllegalArgumentException: Cannot format given Object as a Number

NumberFormat#setGroupingUsed(boolean newValue);  设置整数部分是否使用 "," 3个为一组进行分组,默认为 true。

java.text.DecimalFormat#applyPattern(java.lang.String pattern) 数字格式化模式:

"." ———— 表示小数点。
"," ———— 用于分组,不要用于小数部分。比如千分位:#,###.0000
"0"、"#" —相当于占位符,区别在于实际值位数小于实际值时如何处理,举例如下:

1)##.#### 与 00.0000,对于 3.14,前者返回 3.14,后者返回 03.1400

2) #,###.00 与 #,##0.00 对于 0.78,前者返回 .78,后者返回 0.78

数字格式化演示

@Test
    public void testFormat1() {
        //建立货币格式化引用
        NumberFormat currency = NumberFormat.getCurrencyInstance();
        //建立百分比格式化引用
        NumberFormat percent = NumberFormat.getPercentInstance();
        //百分比小数点最多3位
        percent.setMaximumFractionDigits(3);

        //贷款金额
        BigDecimal loanAmount = new BigDecimal("15000.48");
        //利率
        BigDecimal interestRate = new BigDecimal("0.008");
        //相乘
        BigDecimal interest = loanAmount.multiply(interestRate);

        // 贷款金额:	¥15,000.48
        System.out.println("贷款金额:\t" + currency.format(loanAmount));
        // 利率:	0.8%
        System.out.println("利率:\t" + percent.format(interestRate));
        // 利息:	¥120.00
        System.out.println("利息:\t" + currency.format(interest));

        // 整数格式化格式引用,按小数点后一位进行四舍五入,去掉小数,保留整数,并含有千分位符号
        NumberFormat integerInstance = NumberFormat.getIntegerInstance();
        // 通用数字格式引用,对数值标记千分位符号。
        NumberFormat numberInstance = NumberFormat.getNumberInstance();
        // 14,545,121
        System.out.println(integerInstance.format(new BigDecimal("14545121.451212")));
        // -14,545,122
        System.out.println(integerInstance.format(new BigDecimal("-14545121.551212")));

        // 14,545,121.451
        System.out.println(numberInstance.format(new BigDecimal("14545121.451212")));
        // -14,545,121.551
        System.out.println(numberInstance.format(new BigDecimal("-14545121.551212")));
    }

在线源码:https://gitee.com/wangmx1993/java-se/blob/master/src/test/java/org/example/se/NumberFormatTest.java

随机数生成器 Random

Random 性能问题

1、使用 Random 类时,为了避免重复创建的开销,通常将实例化好的 Random 对象设置为服务对象的属性或静态属性,这在线程竞争不激烈的情况下没有问题,但高并发时,使用同一个 Random 对象可能会导致线程阻塞。

2、Random 的随机原理是对一个'随机种子'进行固定的算术和位运算,得到随机结果,再使用这个结果作为下一次随机的种子。在解决线程安全问题时,Random 使用 CAS 更新下一次随机的种子,可以想到,如果多个线程同时使用这个对象,就肯定会有一些线程执行 CAS 连续失败,进而导致线程阻塞。

ThreadLocalRandom

1、Java jdk 1.7 开始在 concurrent 包内添加了 ThreadLocalRandom 类,与当前线程隔离的随机数生成器。

2、ThreadLocalRandom 通常应该是这样的形式: ThreadLocalRandom.current().nextX(...) (其中X是Int , Long ,等),当所有用法都是这种形式时,绝对不可能跨多个线程共享一个ThreadLocalRandom。

3、ThreadLocalRandom 还提供了其他常用的有界随机生成方法,ThreadLocalRandom 不是加密安全的,在安全敏感的应用程序中考虑使用 SecureRandom。

SecureRandom

1、SecureRandom 提供了一个密码强的随机数生成器,调用者通过无参数构造函数或 getInstance 方法之一获取一个 SecureRandom 实例。

    /**
     * 实际项目中不推荐使用 Random、建议使用 ThreadLocalRandom、SecureRandom
     * int nextInt():返回此随机数生成器序列中的下一个伪随机,包括负数,如 -8022357372481675815
     * long nextLong():返回此随机数生成器序列中的下一个伪随机,包括负数,如 -686133030
     * int nextInt(int bound):返回 [0,bound) 之间的随机数
     * boolean nextBoolean():随机返回 true 或者 false.
     * double nextDouble(): 返回 (0,1) 之间的随机浮点型,如 0.22474496933706056
     * float nextFloat():返回 (0,1) 之间的随机浮点型,如 0.9701549
     */
    @Test
    public void testRandom() {
        System.out.println(new Random().nextInt());
        System.out.println(new Random().nextInt(1000));
        System.out.println(new Random().nextBoolean());
        System.out.println(new Random().nextDouble());
        System.out.println(new Random().nextFloat());
        System.out.println(new Random().nextLong());
    }

    /**
     * Java jdk 1.7 开始在 concurrent 包内添加了 ThreadLocalRandom 类,与当前线程隔离的随机数生成器。
     * ThreadLocalRandom 不是加密安全的,在安全敏感的应用程序中考虑使用 SecureRandom。
     */
    @Test
    public void testSecureRandom2() {
        System.out.println(ThreadLocalRandom.current().nextInt());
        System.out.println(ThreadLocalRandom.current().nextInt(1000));
        System.out.println(ThreadLocalRandom.current().nextBoolean());
        System.out.println(ThreadLocalRandom.current().nextDouble());
        System.out.println(ThreadLocalRandom.current().nextFloat());
        System.out.println(ThreadLocalRandom.current().nextLong());
    }

    /**
     * SecureRandom 提供了一个密码强的随机数生成器,调用者通过无参数构造函数或 getInstance 方法之一获取一个 SecureRandom 实例。
     */
    @Test
    public void testSecureRandom() {
        System.out.println(new SecureRandom().nextInt());
        System.out.println(new SecureRandom().nextInt(1000));
        System.out.println(new SecureRandom().nextBoolean());
        System.out.println(new SecureRandom().nextDouble());
        System.out.println(new SecureRandom().nextFloat());
        System.out.println(new SecureRandom().nextLong());
    }

src/main/java/org/example/uitls/RandomTest.java · 汪少棠/java-se - Gitee.com

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蚩尤后裔-汪茂雄

芝兰生于深林,不以无人而不芳。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值