Skip to content

Commit 256879f

Browse files
committed
Add BigDecimal 使用指南
1 parent 8b0681b commit 256879f

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

docs/java/Java疑难点.md

+88-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,87 @@
99

1010
<!-- /TOC -->
1111

12+
# 基础
13+
14+
## 整形包装类值的比较
15+
16+
所有整形包装类对象值得比较必须使用equals方法。
17+
18+
先看下面这个例子:
19+
20+
```java
21+
Integer x = 3;
22+
Integer y = 3;
23+
System.out.println(x == y);// true
24+
Integer a = new Integer(3);
25+
Integer b = new Integer(3);
26+
System.out.println(a == b);//false
27+
System.out.println(a.equals(b));//false
28+
```
29+
30+
当使用自动装箱方式创建一个Integer对象时,当数值在-128 ~127时,会将创建的Integer对象缓存起来,当下次再出现该数值时,直接从缓存中取出对应的Integer对象。所以上述代码中,x和y引用的是相同的Integer对象。
31+
32+
注意:如果你的IDE(IDEA/Eclipse)上安装了阿里巴巴的p3c插件,这个插件如果检测到你用 ==的话会报错提示,推荐安装一个这个插件,很不错。
33+
34+
35+
36+
## BigDecimal
37+
38+
### BigDecimal 的用处
39+
40+
《阿里巴巴Java开发手册》中提到:**浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals 来判断。** 具体原理和浮点数的编码方式有关,这里就不多提了,我们下面直接上实例:
41+
42+
```java
43+
float a = 1.0f - 0.9f;
44+
float b = 0.9f - 0.8f;
45+
System.out.println(a);// 0.100000024
46+
System.out.println(b);// 0.099999964
47+
System.out.println(a == b);// false
48+
```
49+
具有基本数学知识的我们很清楚的知道输出并不是我们想要的结果(**精度丢失**),我们如何解决这个问题呢?一种很常用的方法是:**使用使用 BigDecimal 来定义浮点数的值,再进行浮点数的运算操作。**
50+
51+
```java
52+
BigDecimal a = new BigDecimal("1.0");
53+
BigDecimal b = new BigDecimal("0.9");
54+
BigDecimal c = new BigDecimal("0.8");
55+
BigDecimal x = a.subtract(b);// 0.1
56+
BigDecimal y = b.subtract(c);// 0.1
57+
System.out.println(x.equals(y));// true
58+
```
59+
60+
### BigDecimal 的大小比较
61+
62+
`a.compareTo(b)` : 返回 -1 表示小于,0 表示 等于, 1表示 大于。
63+
64+
```java
65+
BigDecimal a = new BigDecimal("1.0");
66+
BigDecimal b = new BigDecimal("0.9");
67+
System.out.println(a.compareTo(b));// 1
68+
```
69+
### BigDecimal 保留几位小数
70+
71+
通过 `setScale`方法设置保留几位小数以及保留规则。保留规则有挺多种,不需要记,IDEA会提示。
72+
73+
```java
74+
BigDecimal m = new BigDecimal("1.255433");
75+
BigDecimal n = m.setScale(3,BigDecimal.ROUND_HALF_DOWN);
76+
System.out.println(n);// 1.255
77+
```
78+
79+
### BigDecimal 的使用注意事项
80+
81+
注意:我们在使用BigDecimal时,为了防止精度丢失,推荐使用它的**BigDecimal(String)**构造方法来创建对象。《阿里巴巴Java开发手册》对这部分内容也有提到如下图所示。
82+
83+
![BigDecimal](../../images/BigDecimal.png)
84+
85+
### 总结
86+
87+
BigDecimal 主要用来操作(大)浮点数,BigInteger 主要用来操作大整数(超过 long 类型)。
88+
89+
BigDecimal 的实现利用到了 BigInteger, 所不同的是 BigDecimal 加入了小数位的概念
90+
91+
# 集合
92+
1293
## Arrays.asList()使用指南
1394

1495
最近使用`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]);//没有指定类型的话会报错
212293

213294
## 不要在 foreach 循环里进行元素的 remove/add 操作
214295

215-
如果要进行remove操作,可以调用迭代器的 remove 方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身remove/add方法,迭代器都将抛出一个ConcurrentModificationException,这就是单线程状态下产生的 fail-fast 机制。
296+
如果要进行`remove`操作,可以调用迭代器的 `remove `方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身`remove/add`方法,迭代器都将抛出一个`ConcurrentModificationException`,这就是单线程状态下产生的 **fail-fast 机制**
297+
298+
> **fail-fast 机制** :多个线程对 fail-fast 集合进行修改的时,可能会抛出ConcurrentModificationException,单线程下也会出现这种情况,上面已经提到过。
299+
300+
`java.util`包下面的所有的集合类都是fail-fast的,而`java.util.concurrent`包下面的所有的类都是fail-safe的。
301+
302+
![不要在 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)
216303

217-
> fail-fast 机制:多个线程对 fail-fast 集合进行修改的时,可能会抛出ConcurrentModificationException,单线程下也会出现这种情况,上面已经提到过。
218304

219-
java.util包下面的所有的集合类都是fail-fast的,而java.util.concurrent包下面的所有的类都是fail-safe的。
220305

221-
![不要在 foreach 循环里进行元素的 remove/add 操作](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/15497724883532-1.jpg)

images/BigDecimal.png

296 KB
Loading

0 commit comments

Comments
 (0)