每日学学Java开发规范,集合处理(附阿里巴巴Java开发手册(终极版))

news2024/11/27 8:48:12

前言

每次去不同的公司,码不同的代码,适应不同的规范,经常被老大教育规范问题,我都有点走火入魔的感觉,还是要去看看阿里巴巴Java开发规范,从中熟悉一下,纠正自己,码出高效,码出质量

想细看的可以去官网下载,或者下面自取
阿里巴巴Java开发手册(终极版)

五、集合处理

  1. 【强制】关于 hashCode 和 equals 的处理,遵循如下规则:

    1. 只要重写 equals,就必须重写 hashCode。(参考Set集合)
    2. 因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须重写这两个方法。(set作用是去重,假设new 2个对象,年龄都是18,set去重判断他的hashCode不相等,导致去重失败!!)
    3. 如果自定义对象做为 Map 的键,那么必须重写 hashCode 和 equals。(同理)
    • 说明:String 重写了 hashCode 和 equals 方法,所以我们可以非常愉快地使用 String 对象
      作为 key 来使用。
  2. 【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException
    异常,即 java.util.RandomAccessSubList cannot be cast to java.util.ArrayList.

    • 说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是
      ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。
  3. 【强制】在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、
    删除均会产生 ConcurrentModificationException 异常。

  4. 【强制】使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全
    一样的数组,大小就是 list.size()。

    • 说明:使用 toArray 带参方法,入参分配的数组空间不够大时,toArray 方法内部将重新分配内存空间,并返回新数组地址;如果数组元素大于实际所需,下标为[ list.size() ]的数组元素将被置为 null,其它数组元素保持原值,因此最好将方法入参数组大小定义与集合元素个数一致。(数组/集合扩容原理)
    正例:
    List<String> list = new ArrayList<String>(2);
    list.add("guan");
    list.add("bao");
    String[] array = new String[list.size()];
    array = list.toArray(array);
    反例:直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,
    若强转其它类型数组将出现 ClassCastException 错误。
    
  5. 【强制】使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。(老生常谈,具体看看源码就知道为什么了)

    • 说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。
    String[] str = new String[] { "you", "wu" };
    List list = Arrays.asList(str);
    第一种情况:list.add("yangguanbao"); 运行时异常。
    第二种情况:str[0] = "gujin"; 那么 list.get(0)也会随之修改。
    
  6. 【强制】泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用 add 方法,而<? super T>不能使用 get 方法,做为接口调用赋值时易出错。(迷糊吧~,看例子)

    interface Fruit {}
    class Apple implements Fruit {}
    class Orange implements Fruit {}
    
    // 使用 <? extends Fruit>
    List<? extends Fruit> fruits = new ArrayList<Apple>(); // 合法
    // fruits.add(new Apple()); // 编译错误,不允许添加
    Fruit fruit = fruits.get(0); // 可以读取,得到的是Fruit类型
    
    // 使用 <? super Apple>
    List<? super Apple> apples = new ArrayList<Fruit>(); // 合法
    apples.add(new Apple()); // 允许添加
    // Apple apple = apples.get(0); // 编译错误,需要强制转换
    Object obj = apples.get(0); // 只能当作Object处理
    
    • 说明:扩展说一下 PECS(Producer Extends Consumer Super)原则:
    • 第一、频繁往外读取内容的,适合用<? extends T>。(PE 生产者,允许你读取任何T或其子类型的元素,但不允许向集合中添加元素。这保证了类型安全,因为你只关心你能从中得到什么类型的数据。)
    • 第二、经常往里插入的,适合用<? super T>。(因为<? super T>允许你向集合中添加任何T或其父类型的元素,但获取元素时只能当作Object处理。这样可以确保你可以安全地将T及其子类的对象放入集合中。)
  7. 【强制】不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。(并发编程,去熟悉熟悉)

    正例:
    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
    	String item = iterator.next();
    	if (删除元素的条件) {
    		iterator.remove();
    	}
    }
    反例:
    List<String> list = new ArrayList<String>();
    list.add("1");
    list.add("2");
    for (String item : list) {
    	if ("1".equals(item)) {
    		list.remove(item);
    	}
    }
    
  8. 【强制】 在 JDK7 版本及以上,Comparator 要满足如下三个条件,不然 Arrays.sort,Collections.sort 会报IllegalArgumentException 异常。

    • 说明:三个条件如下
    • x,y 的比较结果和 y,x 的比较结果相反
    • x>y,y>z,则 x>z。
    • x=y,则 x,z 比较结果和 y,z 比较结果相同。
    反例:下例中没有处理相等的情况,实际使用中可能会出现异常:
    new Comparator<Student>() {
    	@Override
    	public int compare(Student o1, Student o2) {
    		return o1.getId() > o2.getId() ? 1 : -1;
    	}
    };
    
  9. 【推荐】集合初始化时,指定集合初始值大小。(可以看看hashmap源码,面试加分噢~)

    • 说明:HashMap 使用 HashMap(int initialCapacity) 初始化,
    • 正例:initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即 loaderfactor)默认为 0.75,如果暂时无法确定初始值大小,请设置为 16(即默认值)。
    • 反例:HashMap 需要放置 1024 个元素,由于没有设置容量初始大小,随着元素不断增加,容量 7 次被迫扩大,resize 需要重建 hash 表,严重影响性能。
  10. 【推荐】使用 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 值组合集合。
  11. 【推荐】高度注意 Map 类集合 K/V 能不能存储 null 值的情况,如下表格:
    在这里插入图片描述

    • 反例: 由于 HashMap 的干扰,很多人认为ConcurrentHashMap 是可以置入 null 值,而事实上,存储 null 值时会抛出 NPE 异常。
  12. 【参考】合理利用好集合的有序性(sort)和稳定性(order),避免集合的无序性(unsort)和不稳定性(unorder)带来的负面影响。

    • 说明:有序性是指遍历的结果是按某种比较规则依次排列的。稳定性指集合每次遍历的元素次序是一定的。如:ArrayList 是order/unsort;HashMap 是 unorder/unsort;TreeSet 是order/sort。
  13. 【参考】利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的contains 方法进行遍历、对比、去重操作。

总结

利用不同集合的特性,能快速处理不同的业务,例如Set去重,HashMap,key唯一的特性,已经根据Key获取value达到性能优化。ArrayList和LinkedList的特点去使用。因为有特性,自然就会有缺陷,比如第9点,初始化值,在集合新增数据过程中,会涉及到扩容,每种集合扩容方式都不一样,在新手期间,为了快速编程,很少会去指定集合的初始值,这也导致被老大教育规范。所以,集合处理方面,是很有必要,不只是面试常问,在编码过程中也很重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2207008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KubeSphere v4 开源并发布全新可插拔架构 LuBan

2024 年 10 月 10 日&#xff0c;KubeSphere 开源社区激动地向大家宣布&#xff0c;KubeSphere v4&#xff08;开源版&#xff09;已正式发布&#xff0c;同时发布全新可插拔架构 KubeSphere LuBan。 相较于 KubeSphere 之前所有的版本&#xff0c;KubeSphere v4 可以说是有了…

springboot将logback替换成log4j2

一 为何要替换成log4j2 1.1 log4j2的优点 log4j2使用了两种方式记录日志&#xff1a;AsyncAppender和AsyncLogger。 1.AsyncAppender使用队列异步记录日志&#xff0c;但是一旦队列已满&#xff0c;appender线程需要等待。2.AsyncLogger是采用Disruptor&#xff0c;通过环形…

携程差旅智核系统 | OPENAIGC开发者大赛高校组优秀作品

在第二届拯救者杯OPENAIGC开发者大赛中&#xff0c;涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到&#xff0c;我们特意开设了优秀作品报道专栏&#xff0c;旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者&#xff0c;希望能带给…

【算法】DFS系列之 记忆化搜索

【ps】本篇有 5 道 leetcode OJ。 目录 一、算法简介 二、相关例题 1&#xff09;斐波那契数 .1- 题目解析 .2- 代码编写 2&#xff09;不同路径 .1- 题目解析 .2- 代码编写 3&#xff09;最长递增子序列 .1- 题目解析 .2- 代码编写 4&#xff09;猜数字大小 II …

Linux云计算 |【第四阶段】RDBMS2-DAY5

主要内容&#xff1a; PXC概述、部署PXC&#xff08;自动故障恢复测试&#xff09;、存储引擎、读锁/写锁、表锁/行锁、常用的存储引擎介绍 一、PXC概述 PXC&#xff08;Percona XtraDB Cluster&#xff0c;简称PXC集群&#xff09;&#xff0c;是基于Galera的MySQL高可用集群…

OpenCV 之 实现基于Lucas-Kanade算法的光流追踪

引言 在计算机视觉中&#xff0c;光流是指物体、场景或摄像机之间的相对运动造成的像素变化。光流估计是计算机视觉中的一个基础课题&#xff0c;广泛应用于许多领域&#xff0c;比如自动驾驶汽车、机器人导航、手势识别等。OpenCV是一个开源的计算机视觉库&#xff0c;提供了…

vue使用gdal-async获取tif文件的缩略图

vue使用gdal-async获取tif文件的缩略图 npm i gdal-asyncgdal-async 在Vue组件中使用gdal-async获取缩略图&#xff1a; <template><div><img v-if"thumbnail" :src"thumbnail" alt"Thumbnail" /></div> </templa…

友思特方案 | FantoVision边缘计算:嵌入式视觉系统如何实现“更快 更高 更强”?

导读 便于集成的嵌入式视觉系统一直以来面临着带宽、内存、算力三个方面的挑战。友思特 FantoVision 边缘计算设备拥有更快的处理速度和更高的带宽选择&#xff0c;其开放式架构有效突破了上述三重阻碍。 嵌入式视觉 嵌入式视觉是传统机器视觉衍生出来的子集&#xff0c;嵌入…

STM32移植RT-Thread实现PWM波的输出

在进行PWM波的学习中&#xff0c;依然是踩了小坑&#xff0c;网络上大部分配置都增加了TIM的配置&#xff0c;貌似是不需要的&#xff0c;当开启了TIM的时钟反而影响了PWM的时钟&#xff0c;暂且归咎于版本不一样&#xff1f;还是STM32F1和STM32F4不一样呢&#xff1f;核心问题…

【黑马点评优化】之使用Caffeine+Redis实现应用级二层缓存

【黑马点评优化】之使用CaffeineRedis实现应用级二层缓存 1 缓存雪崩定义及解决方案2 为什么要使用多级缓存3 RedisCaffeine实现应用层二级缓存原理4 利用CaffeineRedis解决Redis突然宕机导致的缓存雪崩问题4.1 pom.xml文件引入相关依赖4.2 本地缓存配置类4.3 修改ShopServiceI…

Blazor Web APP学习记录

目录 1 呈现模式1.1 静态SSR1.2 服务器端交互SSR1.3 客户端交互CSR1.4 自动交互式1.5 注意 2 Blazor Web APP项目3 会话状态 1 呈现模式 参见&#xff1a;https://learn.microsoft.com/zh-cn/aspnet/core/blazor/components/render-modes?viewaspnetcore-8.0 Blazor Web App …

torch-npu的配置

1、简单的调用npu import torch import torch_npu x torch.randn(10000, 10000).npu() y torch.randn(10000, 10000).npu() for _ in range(10000):z x.mm(y) 这个代码的出现就会导致&#xff0c;核心使用99%&#xff0c;显存| 1633 2、安装torch-npu 安装方法看官网介绍…

npm使用时报错:Could not retrieve https://npm.taobao.org/mirrors/node/index.json.

在使用npm时报错&#xff0c;报错信息如下&#xff1a; 报错的原因&#xff1a;是原来的淘宝镜像地址过期了 解决办法&#xff1a;修改镜像地址。打开nvm的安装地址 -->settings.txt文件 -->配置下载源 1、将settings.txt文件中的 node_mirror: https://npm.taobao.or…

机器学习可解释性

机器学习的稳健性、可解释性和结果正确性等是人工智能安全可信应用必须解决的关键问题。 传统机器学习&#xff1a; 内置可解释性&#xff1a;决策树IF-Then规则&#xff0c;直观可理解事后可解释性&#xff1a;训练结束后的可解释技术特定于模型体系结构的解释与解释方法及模…

删除 Word 空白页的 3 种方法总结

在使用 Word 进行文档编辑的时候&#xff0c;空白页的出现常常会让用户感到困扰&#xff0c;Word 空白页的出现可能是由于分页、段落设置以及格式问题&#xff0c;空白页可能会出现在文档的开始、中间及结尾&#xff0c;如果需要打印文档还会影响打印效果&#xff0c;那么 Word…

【论文#性能对比】Video coding with H.264/AVC: Tools, Performance, and Complexity

目录 摘要1.前言2.标准化视频编码方案的概念3. H.264/AVC 编码方案3.1 帧内预测3.2 运动补偿预测3.3 变换编码3.4 熵编码方案3.5 自适应去块滤波器3.6 错误鲁棒性和网络友好性 4.码率受限的编码器控制5. H.264/AVC 的配置文件和级别6.与先前标准的比较6.1 编码效率6.2 硬件复杂…

如何启动一个OpenSearch

创建两个集群&#xff0c;标注 不含备用节点 选择集群版本和配置集群版本 冷热存储和专用主节点这个按需开启 然后是网络&#xff0c;是否使用自定义域名&#xff0c;集群开在VPC还是公网上。 选择是否开启认证&#xff1a; 访问策略&#xff0c;其实就是资源策略 维护时段…

vue页面使用v-print指令打印表格表单的几种方法,包括页眉标题自定义设置

页面效果: 打印预览页面: 步骤: 1.安装vue-print-nb 2.在main.js里面注册 import Print from vue-print-nbVue.use(Print) 3.在页面.vue代码中定义打印范围和打印按钮&#xff0c;我这里是以id"main-div"这个div为范围进行打印 <div> <div id"main-d…

grs认证有什么好处?grs认证相关政策

GRS认证&#xff08;Global Recycled Standard&#xff09;即全球回收标准认证&#xff0c;是一项国际、自愿和全面的产品标准&#xff0c;主要针对回收材料的使用和供应链进行认证。GRS认证能够为企业带来多方面的好处&#xff0c;以下是对这些好处的详细归纳&#xff1a; 一…

【livox雷达】HAP雷达 红外 orin 交换机 ——办公室 硬件搭配

orin&#xff1a;拉一根网线&#xff0c;一端连orin&#xff0c;一端连交换机 雷达&#xff1a;接上电源&#xff0c;另一端连接交换机 红外&#xff1a;用gsml方式连到orin上 交换机&#xff1a;以交换机为中心&#xff0c;连一根网线到orin&#xff0c;一根接外网的网线连给…