↖  Java開發手冊-阿里巴巴-嵩山版-7:集合處理..


Java開發手冊-阿里巴巴-嵩山版-7:集合處理

2020-12-24 , 1514 , 104 , 130

听音频 🔊 . 看视频 🎦

(六) 集合处理-2


8. 【强制】在subList场景中,高度注意对父集合元素的增加或删除,均会导致子列表的遍历、增加、删除产生ConcurrentModificationException 异常。 

9. 【强制】使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一致、长度为0的空数组。 

反例:直接使用toArray无参方法存在问题,此方法返回值只能是Object[]类,若强转其它类型数组将出现ClassCastException错误。 


正例:

List<String> list = new ArrayList<>(2);

list.add("guan");

list.add("bao");

String[] array = list.toArray(new String[0]); 


说明:使用toArray带参方法,数组空间大小的length: 

1) 等于0,动态创建与size相同的数组,性能最好。

2) 大于0但小于size,重新创建大小等于size的数组,增加GC负担。 

3) 等于size,在高并发情况下,数组创建完成之后,size正在变大的情况下,负面影响与2相同。

4) 大于size,空间浪费,且在size处插入null值,存在NPE隐患(NullPointerException )。


10. 【强制】在使用Collection接口任何实现类的addAll()方法时,都要对输入的集合参数进行NPE判断。 

说明:在ArrayList#addAll方法的第一行代码即Object[] a = c.toArray(); 其中c为输入集合参数,如果为null,则直接抛出异常。

11. 【强制】使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。 

说明:asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。 

String[] str = new String[] { "chen", "yang", "hao" }; 

List list = Arrays.asList(str); 

第一种情况:list.add("yangguanbao"); 运行时异常。 

第二种情况:str[0] = "change"; 也会随之修改,反之亦然。


12. 【强制】泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用add方法,而<? super T>不能使用get方法,两者在接口调用赋值的场景中容易出错。 

-loading- -loading--loading-


说明:扩展说一下PECS(Producer Extends Consumer Super)原则:

UfqiLong

第一、频繁往外读取内容的,适合用<? extends T>。

第二、经常往里插入的,适合用<? super T>


13. 【强制】在无泛型限制定义的集合赋值给泛型限制的集合时,在使用集合元素时,需要进行instanceof判断,避免抛出ClassCastException异常。 

说明:毕竟泛型是在JDK5后才出现,考虑到向前兼容,编译器是允许非泛型集合与泛型集合互相赋值。

反例: 

List<String> generics = null; 

List notGenerics = new ArrayList(10); 

notGenerics.add(new Object()); 

notGenerics.add(new Integer(1)); 

generics = notGenerics; // 此处抛出ClassCastException异常 

String string = generics.get(0);


14. 【强制】不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。

正例:

List<String> list = new ArrayList<>();

list.add("1");

list.add("2");

Iterator<String> iterator = list.iterator();

while (iterator.hasNext()) {

String item = iterator.next();

if (删除元素的条件) {

iterator.remove();

}

}


反例:

for (String item : list) {

if ("1".equals(item)) {

list.remove(item);

}

}

说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结果吗?


15. 【强制】在JDK7版本及以上,Comparator实现类要满足如下三个条件,不然Arrays.sort,Collections.sort会抛IllegalArgumentException异常。 

说明:三个条件如下 

1) x,y的比较结果和y,x的比较结果相反。 

2) x>y,y>z,则x>z。 

3) x=y,则x,z比较结果和y,z比较结果相同。 

反例:下例中没有处理相等的情况,交换两个对象判断结果并不互反,不符合第一个条件,在实际使用中 可能会出现异常。

new Comparator<Student>() {

@Override

public int compare(Student o1, Student o2) {

return o1.getId() > o2.getId() ? 1 : -1;

}

};


16. 【推荐】集合泛型定义时,在JDK7及以上,使用diamond语法或全省略。

说明:菱形泛型,即diamond,直接使用<>来指代前边已经指定的类型。

-loading- -loading--loading-


UfqiLong

正例:

// diamond方式,即<>

HashMap<String, String> userCache = new HashMap<>(16);

// 全省略方式

ArrayList<User> users = new ArrayList(10);


17. 【推荐】集合初始化时,指定集合初始值大小。 

说明:HashMap使用HashMap(int initialCapacity) 初始化,如果暂时无法确定集合大小,那么指定默认值(16)即可。

正例:

initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即loader factor)默认为0.75,如果暂时无法确定初始值大小,请设置为16(即默认值)。

反例: 

HashMap需要放置1024个元素,由于没有设置容量初始大小,随着元素增加而被迫不断扩容,resize()方法总共会调用8次,反复重建哈希表和数据迁移。当放置的集合元素个数达千万级时会影响程序性能。


18. 【推荐】使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历。 

说明:keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.forEach方法。 

正例:values()返回的是V值集合,是一个list集合对象;keySet()返回的是K值集合,是一个Set集合对象;entrySet()返回的是K-V值组合集合。


19. 【推荐】高度注意Map类集合K/V能不能存储null值的情况,如下表格:

java-map-null.JPG

反例:由于HashMap的干扰,很多人认为ConcurrentHashMap是可以置入null值,而事实上,存储null值时会抛出NPE异常。


20. 【参考】合理利用好集合的有序性(sort)和稳定性(order),避免集合的无序性(unsort)和不稳定性(unorder)带来的负面影响。 

说明:有序性是指遍历的结果是按某种比较规则依次排列的。稳定性指集合每次遍历的元素次序是一定的。

如:ArrayList是order/unsort;HashMap是unorder/unsort;TreeSet是order/sort。

21. 【参考】利用Set元素唯一的特性,可以快速对一个集合进行去重操作,避免使用List的contains()进行遍历去重或者判断包含操作。


+手冊 +嵩山 +数组 +反例 +泛型

本页Url

↖回首页 +当前续 +尾续 +修订 +评论✍️


👍6 仁智互见 👎0
  • 还没有评论. → +评论
  • -loading- -loading- -loading-


    🔗 连载目录

    🤖 智能推荐

    Java開發手冊-阿里巴巴-嵩山版

    畅游山海 万里联通 26

    白天爬山夜里赶路 人称“最强特种兵” 成都小伙五一登遍五岳震惊网友 18

    让我们一起追寻金庸论剑足迹,感受五岳魅力 17

    小伙回应“五天爬五岳”被质疑!计划表让网友沉默了 17

    小伙“五一闪现五岳”:抢票比登山更难,不主张网友模仿 14

    诸城竹山、临朐嵩山获评2023年山东省生态旅游区 诸城竹山、临朐嵩山获评2023年山东省生态旅游区 12

    到2035年,嵩山实验室这样建 12

    登封:何以为中?以和为“中”! 10

    接待游客272万人次!登封中秋国庆假期文旅市场超“燃” 接待游客272万人次!登封中秋国庆假期文旅市场超“燃” 3

    -loading- -loading- -loading-


    🔥 相关精选

    嵩山首秀数字“功夫”,世界第一枚旅游徽章集结“特种兵” 3

    (寻味中华丨文博)嵩阳书院:古韵悠悠,文风不息 (寻味中华丨文博)嵩阳书院:古韵悠悠,文风不息 2

    骂上热搜,有些音乐节不如不办? 2

    博物馆里的文化年 1

    一路铺展乡村振兴新画卷 1

    如何从嵩山走向世界 全国40余家主流媒体记者实地打卡嵩山少林武术职业学院 如何从嵩山走向世界 全国40余家主流媒体记者实地打卡嵩山少林武术职业学院 1

    世界眼中的中国功夫什么样?嵩山风云下他们讲出中国故事 世界眼中的中国功夫什么样?嵩山风云下他们讲出中国故事 1

    环翠分局嵩山路派出所注重“四心”培养,全面加强辅警队伍管理工作 1

    当下地产行业的真实表现 0

    潍坊临朐乡村旅游精品线路获全国推介 潍坊临朐乡村旅游精品线路获全国推介 0

    -loading- -loading- -loading-

     


    + 黄晓武 黄晓武
    AddToFav   
    新闻 经典 官宣