1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-20 22:17:09 +08:00

Add BigDecimal 使用指南

This commit is contained in:
SnailClimb 2019-07-14 14:43:03 +08:00
parent 8b0681be14
commit 256879fd2c
2 changed files with 88 additions and 4 deletions

View File

@ -9,6 +9,87 @@
<!-- /TOC --> <!-- /TOC -->
# 基础
## 整形包装类值的比较
所有整形包装类对象值得比较必须使用equals方法。
先看下面这个例子:
```java
Integer x = 3;
Integer y = 3;
System.out.println(x == y);// true
Integer a = new Integer(3);
Integer b = new Integer(3);
System.out.println(a == b);//false
System.out.println(a.equals(b));//false
```
当使用自动装箱方式创建一个Integer对象时当数值在-128 ~127时会将创建的Integer对象缓存起来当下次再出现该数值时直接从缓存中取出对应的Integer对象。所以上述代码中x和y引用的是相同的Integer对象。
注意如果你的IDE(IDEA/Eclipse)上安装了阿里巴巴的p3c插件这个插件如果检测到你用 ==的话会报错提示,推荐安装一个这个插件,很不错。
## BigDecimal
### BigDecimal 的用处
《阿里巴巴Java开发手册》中提到**浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals 来判断。** 具体原理和浮点数的编码方式有关,这里就不多提了,我们下面直接上实例:
```java
float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
System.out.println(a);// 0.100000024
System.out.println(b);// 0.099999964
System.out.println(a == b);// false
```
具有基本数学知识的我们很清楚的知道输出并不是我们想要的结果(**精度丢失**),我们如何解决这个问题呢?一种很常用的方法是:**使用使用 BigDecimal 来定义浮点数的值,再进行浮点数的运算操作。**
```java
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");
BigDecimal x = a.subtract(b);// 0.1
BigDecimal y = b.subtract(c);// 0.1
System.out.println(x.equals(y));// true
```
### BigDecimal 的大小比较
`a.compareTo(b)` : 返回 -1 表示小于0 表示 等于, 1表示 大于。
```java
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
System.out.println(a.compareTo(b));// 1
```
### BigDecimal 保留几位小数
通过 `setScale`方法设置保留几位小数以及保留规则。保留规则有挺多种不需要记IDEA会提示。
```java
BigDecimal m = new BigDecimal("1.255433");
BigDecimal n = m.setScale(3,BigDecimal.ROUND_HALF_DOWN);
System.out.println(n);// 1.255
```
### BigDecimal 的使用注意事项
注意我们在使用BigDecimal时为了防止精度丢失推荐使用它的**BigDecimal(String)**构造方法来创建对象。《阿里巴巴Java开发手册》对这部分内容也有提到如下图所示。
![BigDecimal](../../images/BigDecimal.png)
### 总结
BigDecimal 主要用来操作浮点数BigInteger 主要用来操作大整数(超过 long 类型)。
BigDecimal 的实现利用到了 BigInteger, 所不同的是 BigDecimal 加入了小数位的概念
# 集合
## Arrays.asList()使用指南 ## Arrays.asList()使用指南
最近使用`Arrays.asList()`遇到了一些坑,然后在网上看到这篇文章:[Java Array to List Examples](http://javadevnotes.com/java-array-to-list-examples) 感觉挺不错的,但是还是特别全面。所以,自己对于这块小知识点进行了简单的总结。 最近使用`Arrays.asList()`遇到了一些坑,然后在网上看到这篇文章:[Java Array to List Examples](http://javadevnotes.com/java-array-to-list-examples) 感觉挺不错的,但是还是特别全面。所以,自己对于这块小知识点进行了简单的总结。
@ -212,10 +293,13 @@ s=list.toArray(new String[0]);//没有指定类型的话会报错
## 不要在 foreach 循环里进行元素的 remove/add 操作 ## 不要在 foreach 循环里进行元素的 remove/add 操作
如果要进行remove操作可以调用迭代器的 remove 方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后以任何方式除非通过迭代器自身remove/add方法迭代器都将抛出一个ConcurrentModificationException,这就是单线程状态下产生的 fail-fast 机制。 如果要进行`remove`操作,可以调用迭代器的 `remove `方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身`remove/add`方法,迭代器都将抛出一个`ConcurrentModificationException`,这就是单线程状态下产生的 **fail-fast 机制**
> **fail-fast 机制** :多个线程对 fail-fast 集合进行修改的时可能会抛出ConcurrentModificationException单线程下也会出现这种情况上面已经提到过。
`java.util`包下面的所有的集合类都是fail-fast的`java.util.concurrent`包下面的所有的类都是fail-safe的。
![不要在 foreach 循环里进行元素的 remove/add 操作](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/Screenshot 2019-07-14 at 1.31.09 PM.png)
> fail-fast 机制:多个线程对 fail-fast 集合进行修改的时可能会抛出ConcurrentModificationException单线程下也会出现这种情况上面已经提到过。
java.util包下面的所有的集合类都是fail-fast的而java.util.concurrent包下面的所有的类都是fail-safe的。
![不要在 foreach 循环里进行元素的 remove/add 操作](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/15497724883532-1.jpg)

BIN
images/BigDecimal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB