目录
DecimalFormat 与 NumberFormat 数值格式化
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 (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) 数字格式化模式:
"." ———— 表示小数点。 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