1- <!-- TOC -->
2-
3- - [ 1. 基础] ( #1-基础 )
4- - [ 1.1. 正确使用 equals 方法] ( #11-正确使用-equals-方法 )
5- - [ 1.2. 整型包装类值的比较] ( #12-整型包装类值的比较 )
6- - [ 1.3. BigDecimal] ( #13-bigdecimal )
7- - [ 1.3.1. BigDecimal 的用处] ( #131-bigdecimal-的用处 )
8- - [ 1.3.2. BigDecimal 的大小比较] ( #132-bigdecimal-的大小比较 )
9- - [ 1.3.3. BigDecimal 保留几位小数] ( #133-bigdecimal-保留几位小数 )
10- - [ 1.3.4. BigDecimal 的使用注意事项] ( #134-bigdecimal-的使用注意事项 )
11- - [ 1.3.5. 总结] ( #135-总结 )
12- - [ 1.4. 基本数据类型与包装数据类型的使用标准] ( #14-基本数据类型与包装数据类型的使用标准 )
13- - [ 2. 集合] ( #_2-集合 )
14- - [ 2.1. Arrays.asList()使用指南] ( #21-arraysaslist使用指南 )
15- - [ 2.1.1. 简介] ( #211-简介 )
16- - [ 2.1.2. 《阿里巴巴Java 开发手册》对其的描述] ( #212-阿里巴巴java-开发手册对其的描述 )
17- - [ 2.1.3. 使用时的注意事项总结] ( #213-使用时的注意事项总结 )
18- - [ 2.1.4. 如何正确的将数组转换为ArrayList?] ( #214-如何正确的将数组转换为arraylist )
19- - [ 2.2. Collection.toArray()方法使用的坑&如何反转数组] ( #22-collectiontoarray方法使用的坑如何反转数组 )
20- - [ 2.3. 不要在 foreach 循环里进行元素的 remove/add 操作] ( #23-不要在-foreach-循环里进行元素的-removeadd-操作 )
21-
22- <!-- /TOC -->
23-
24- # 1. 基础
25-
26- ## 1.1. 正确使用 equals 方法
1+ ## 正确使用 equals 方法
272
283Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。
294
@@ -65,7 +40,7 @@ Reference:[Java中equals方法造成空指针异常的原因及解决方案](htt
6540- 可以使用 == 或者 != 操作来比较null值,但是不能使用其他算法或者逻辑操作。在Java中` null == null ` 将返回true。
6641- 不能使用一个值为null的引用类型变量来调用非静态方法,否则会抛出异常
6742
68- ## 1.2. 整型包装类值的比较
43+ ## 整型包装类值的比较
6944
7045所有整型包装类对象值的比较必须使用equals方法。
7146
@@ -85,9 +60,9 @@ System.out.println(i1==i2);//false
8560
8661** 注意:** 如果你的IDE(IDEA/Eclipse)上安装了阿里巴巴的p3c插件,这个插件如果检测到你用 ==的话会报错提示,推荐安装一个这个插件,很不错。
8762
88- ## 1.3. BigDecimal
63+ ## BigDecimal
8964
90- ### 1.3.1. BigDecimal 的用处
65+ ### BigDecimal 的用处
9166
9267《阿里巴巴Java开发手册》中提到:** 浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals 来判断。** 具体原理和浮点数的编码方式有关,这里就不多提了,我们下面直接上实例:
9368
@@ -113,7 +88,7 @@ System.out.println(y); /* 0.1 */
11388System . out. println(Objects . equals(x, y)); /* true */
11489```
11590
116- ### 1.3.2. BigDecimal 的大小比较
91+ ### BigDecimal 的大小比较
11792
11893` a.compareTo(b) ` : 返回 -1 表示 ` a ` 小于 ` b ` ,0 表示 ` a ` 等于 ` b ` , 1表示 ` a ` 大于 ` b ` 。
11994
@@ -122,7 +97,7 @@ BigDecimal a = new BigDecimal("1.0");
12297BigDecimal b = new BigDecimal (" 0.9" );
12398System . out. println(a. compareTo(b));// 1
12499```
125- ### 1.3.3. BigDecimal 保留几位小数
100+ ### BigDecimal 保留几位小数
126101
127102通过 ` setScale ` 方法设置保留几位小数以及保留规则。保留规则有挺多种,不需要记,IDEA会提示。
128103
@@ -132,19 +107,19 @@ BigDecimal n = m.setScale(3,BigDecimal.ROUND_HALF_DOWN);
132107System . out. println(n);// 1.255
133108```
134109
135- ### 1.3.4. BigDecimal 的使用注意事项
110+ ### BigDecimal 的使用注意事项
136111
137112注意:我们在使用BigDecimal时,为了防止精度丢失,推荐使用它的 ** BigDecimal(String)** 构造方法来创建对象。《阿里巴巴Java开发手册》对这部分内容也有提到如下图所示。
138113
139114![ 《阿里巴巴Java开发手册》对这部分BigDecimal的描述] ( https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/BigDecimal.png )
140115
141- ### 1.3.5. 总结
116+ ### 总结
142117
143118BigDecimal 主要用来操作(大)浮点数,BigInteger 主要用来操作大整数(超过 long 类型)。
144119
145120BigDecimal 的实现利用到了 BigInteger, 所不同的是 BigDecimal 加入了小数位的概念
146121
147- ## 1.4. 基本数据类型与包装数据类型的使用标准
122+ ## 基本数据类型与包装数据类型的使用标准
148123
149124Reference:《阿里巴巴Java开发手册》
150125
@@ -160,237 +135,3 @@ Reference:《阿里巴巴Java开发手册》
160135
161136** 反例** : 比如显示成交总额涨跌情况,即正负 x%,x 为基本数据类型,调用的 RPC 服务,调用不成功时,返回的是默认值,页面显示为 0%,这是不合理的,应该显示成中划线。所以包装数据类型的 null 值,能够表示额外的信息,如:远程调用失败,异常退出。
162137
163- # 2. 集合
164-
165- ## 2.1. Arrays.asList()使用指南
166-
167- 最近使用` Arrays.asList() ` 遇到了一些坑,然后在网上看到这篇文章:[ Java Array to List Examples] ( http://javadevnotes.com/java-array-to-list-examples ) 感觉挺不错的,但是还不是特别全面。所以,自己对于这块小知识点进行了简单的总结。
168-
169- ### 2.1.1. 简介
170-
171- ` Arrays.asList() ` 在平时开发中还是比较常见的,我们可以使用它将一个数组转换为一个List集合。
172-
173- ``` java
174- String [] myArray = {" Apple" , " Banana" , " Orange" };
175- List<String > myList = Arrays . asList(myArray);
176- // 上面两个语句等价于下面一条语句
177- List<String > myList = Arrays . asList(" Apple" ," Banana" , " Orange" );
178- ```
179-
180- JDK 源码对于这个方法的说明:
181-
182- ``` java
183- /**
184- *返回由指定数组支持的固定大小的列表。此方法作为基于数组和基于集合的API之间的桥梁,
185- * 与 Collection.toArray()结合使用。返回的List是可序列化并实现RandomAccess接口。
186- */
187- public static < T > List<T > asList(T . .. a) {
188- return new ArrayList<> (a);
189- }
190- ```
191-
192- ### 2.1.2. 《阿里巴巴Java 开发手册》对其的描述
193-
194- ` Arrays.asList() ` 将数组转换为集合后,底层其实还是数组,《阿里巴巴Java 开发手册》对于这个方法有如下描述:
195-
196- ![ 阿里巴巴Java开发手-Arrays.asList()方法] ( https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/阿里巴巴Java开发手-Arrays.asList()方法.png )
197-
198- ### 2.1.3. 使用时的注意事项总结
199-
200- ** 传递的数组必须是对象数组,而不是基本类型。**
201-
202- ` Arrays.asList() ` 是泛型方法,传入的对象必须是对象数组。
203-
204- ``` java
205- int [] myArray = {1 , 2 , 3 };
206- List myList = Arrays . asList(myArray);
207- System . out. println(myList. size());// 1
208- System . out. println(myList. get(0 ));// 数组地址值
209- System . out. println(myList. get(1 ));// 报错:ArrayIndexOutOfBoundsException
210- int [] array = (int []) myList. get(0 );
211- System . out. println(array[0 ]);// 1
212- ```
213- 当传入一个原生数据类型数组时,` Arrays.asList() ` 的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组,这也就解释了上面的代码。
214-
215- 我们使用包装类型数组就可以解决这个问题。
216-
217- ``` java
218- Integer [] myArray = {1 , 2 , 3 };
219- ```
220-
221- ** 使用集合的修改方法:` add() ` 、` remove() ` 、` clear() ` 会抛出异常。**
222-
223- ``` java
224- List myList = Arrays . asList(1 , 2 , 3 );
225- myList. add(4 );// 运行时报错:UnsupportedOperationException
226- myList. remove(1 );// 运行时报错:UnsupportedOperationException
227- myList. clear();// 运行时报错:UnsupportedOperationException
228- ```
229-
230- ` Arrays.asList() ` 方法返回的并不是 ` java.util.ArrayList ` ,而是 ` java.util.Arrays ` 的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法。
231-
232- ``` java
233- List myList = Arrays . asList(1 , 2 , 3 );
234- System . out. println(myList. getClass());// class java.util.Arrays$ArrayList
235- ```
236-
237- 下图是` java.util.Arrays$ArrayList ` 的简易源码,我们可以看到这个类重写的方法有哪些。
238-
239- ``` java
240- private static class ArrayList <E> extends AbstractList<E >
241- implements RandomAccess , java.io. Serializable
242- {
243- ...
244-
245- @Override
246- public E get (int index ) {
247- ...
248- }
249-
250- @Override
251- public E set (int index , E element ) {
252- ...
253- }
254-
255- @Override
256- public int indexOf (Object o ) {
257- ...
258- }
259-
260- @Override
261- public boolean contains (Object o ) {
262- ...
263- }
264-
265- @Override
266- public void forEach (Consumer<? super E > action ) {
267- ...
268- }
269-
270- @Override
271- public void replaceAll (UnaryOperator<E > operator ) {
272- ...
273- }
274-
275- @Override
276- public void sort (Comparator<? super E > c ) {
277- ...
278- }
279- }
280- ```
281-
282- 我们再看一下` java.util.AbstractList ` 的` remove() ` 方法,这样我们就明白为啥会抛出` UnsupportedOperationException ` 。
283-
284- ``` java
285- public E remove(int index) {
286- throw new UnsupportedOperationException ();
287- }
288- ```
289-
290- ### 2.1.4. 如何正确的将数组转换为ArrayList?
291-
292- stackoverflow:https://dwz.cn/vcBkTiTW
293-
294- ** 1. 自己动手实现(教育目的)**
295-
296- ``` java
297- // JDK1.5+
298- static < T > List<T > arrayToList(final T [] array) {
299- final List<T > l = new ArrayList<T > (array. length);
300-
301- for (final T s : array) {
302- l. add(s);
303- }
304- return l;
305- }
306- ```
307-
308- ``` java
309- Integer [] myArray = { 1 , 2 , 3 };
310- System . out. println(arrayToList(myArray). getClass());// class java.util.ArrayList
311- ```
312-
313- ** 2. 最简便的方法(推荐)**
314-
315- ``` java
316- List list = new ArrayList<> (Arrays . asList(" a" , " b" , " c" ))
317- ```
318-
319- ** 3. 使用 Java8 的Stream(推荐)**
320-
321- ``` java
322- Integer [] myArray = { 1 , 2 , 3 };
323- List myList = Arrays . stream(myArray). collect(Collectors . toList());
324- // 基本类型也可以实现转换(依赖boxed的装箱操作)
325- int [] myArray2 = { 1 , 2 , 3 };
326- List myList = Arrays . stream(myArray2). boxed(). collect(Collectors . toList());
327- ```
328-
329- ** 4. 使用 Guava(推荐)**
330-
331- 对于不可变集合,你可以使用[ ` ImmutableList ` ] ( https://github.com/google/guava/blob/master/guava/src/com/google/common/collect/ImmutableList.java ) 类及其[ ` of() ` ] ( https://github.com/google/guava/blob/master/guava/src/com/google/common/collect/ImmutableList.java#L101 ) 与[ ` copyOf() ` ] ( https://github.com/google/guava/blob/master/guava/src/com/google/common/collect/ImmutableList.java#L225 ) 工厂方法:(参数不能为空)
332-
333- ``` java
334- List<String > il = ImmutableList . of(" string" , " elements" ); // from varargs
335- List<String > il = ImmutableList . copyOf(aStringArray); // from array
336- ```
337- 对于可变集合,你可以使用[ ` Lists ` ] ( https://github.com/google/guava/blob/master/guava/src/com/google/common/collect/Lists.java ) 类及其[ ` newArrayList() ` ] ( https://github.com/google/guava/blob/master/guava/src/com/google/common/collect/Lists.java#L87 ) 工厂方法:
338-
339- ``` java
340- List<String > l1 = Lists . newArrayList(anotherListOrCollection); // from collection
341- List<String > l2 = Lists . newArrayList(aStringArray); // from array
342- List<String > l3 = Lists . newArrayList(" or" , " string" , " elements" ); // from varargs
343- ```
344-
345- ** 5. 使用 Apache Commons Collections**
346-
347- ``` java
348- List<String > list = new ArrayList<String > ();
349- CollectionUtils . addAll(list, str);
350- ```
351-
352- ** 6. 使用 Java9 的 ` List.of() ` 方法**
353- ``` java
354- Integer [] array = {1 , 2 , 3 };
355- List<Integer > list = List . of(array);
356- System . out. println(list); /* [1, 2, 3] */
357- /* 不支持基本数据类型 */
358- ```
359-
360- ## 2.2. Collection.toArray()方法使用的坑&如何反转数组
361-
362- 该方法是一个泛型方法:` <T> T[] toArray(T[] a); ` 如果` toArray ` 方法中没有传递任何参数的话返回的是` Object ` 类型数组。
363-
364- ``` java
365- String [] s= new String []{
366- " dog" , " lazy" , " a" , " over" , " jumps" , " fox" , " brown" , " quick" , " A"
367- };
368- List<String > list = Arrays . asList(s);
369- Collections . reverse(list);
370- s= list. toArray(new String [0 ]);// 没有指定类型的话会报错
371- ```
372-
373- 由于JVM优化,` new String[0] ` 作为` Collection.toArray() ` 方法的参数现在使用更好,` new String[0] ` 就是起一个模板的作用,指定了返回数组的类型,0是为了节省空间,因为它只是为了说明返回的类型。详见:< https://shipilev.net/blog/2016/arrays-wisdom-ancients/ >
374-
375- ## 2.3. 不要在 foreach 循环里进行元素的 remove/add 操作
376-
377- 如果要进行` remove ` 操作,可以调用迭代器的 ` remove ` 方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身` remove/add ` 方法,迭代器都将抛出一个` ConcurrentModificationException ` ,这就是单线程状态下产生的 ** fail-fast 机制** 。
378-
379- > ** fail-fast 机制** :多个线程对 fail-fast 集合进行修改的时候,可能会抛出ConcurrentModificationException,单线程下也会出现这种情况,上面已经提到过。
380-
381- Java8开始,可以使用` Collection#removeIf() ` 方法删除满足特定条件的元素,如
382- ``` java
383- List<Integer > list = new ArrayList<> ();
384- for (int i = 1 ; i <= 10 ; ++ i) {
385- list. add(i);
386- }
387- list. removeIf(filter - > filter % 2 == 0 ); /* 删除list中的所有偶数 */
388- System . out. println(list); /* [1, 3, 5, 7, 9] */
389- ```
390-
391- ` java.util ` 包下面的所有的集合类都是fail-fast的,而` java.util.concurrent ` 包下面的所有的类都是fail-safe的。
392-
393- ![ 不要在 foreach 循环里进行元素的 remove/add 操作] ( https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/foreach-remove:add.png )
394-
395-
396-
0 commit comments