首页 > 编程语言 >每日学学Java开发规范,集合处理(附阿里巴巴Java开发手册(终极版))

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

时间:2024-10-16 21:32:38浏览次数:1  
标签:终极版 Java ArrayList 元素 list add 开发 集合 new

前言

每次去不同的公司,码不同的代码,适应不同的规范,经常被老大教育规范问题,我都有点走火入魔的感觉,还是要去看看阿里巴巴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点,初始化值,在集合新增数据过程中,会涉及到扩容,每种集合扩容方式都不一样,在新手期间,为了快速编程,很少会去指定集合的初始值,这也导致被老大教育规范。所以,集合处理方面,是很有必要,不只是面试常问,在编码过程中也很重要。

标签:终极版,Java,ArrayList,元素,list,add,开发,集合,new
From: https://www.cnblogs.com/xswz/p/18470973

相关文章

  • AI程序开发体验之CRM系统
    一、CRM系统的核心功能CRM系统是企业用于管理与客户关系的软件,它通过集成多种功能来提升客户满意度和企业效率。以下是一些CRM系统的核心功能:客户数据管理:这是CRM系统的基础功能,允许企业存储和组织客户的联系信息、购买历史和偏好等数据,以便快速访问并提供个性化服务。销......
  • Java 集成阿里云发送短信
    首先要有个阿里云账号,可到阿里云登录页注册并登录。登录后访问短信服务快速学习和测试,其中有逐步介绍如何发送短信:新增资质新增资质相当于进行实名认证,资质是申请签名的实名化信息。申请签名签名是短信中能代表发送者属性的字段。一般就是公司名字。发送短信时,签名会附加到......
  • Java算法竞赛之HashMap常用API--哈西表!
    在Java算法竞赛中,HashMap是一个非常重要的数据结构,它提供了许多有用的API来方便地进行键值对的存储、检索和更新。除了getOrDefault方法外,HashMap还有其他一些常用的API。以下是一些主要的HashMapAPI及其在算法竞赛中的常见用法:put(Kkey,Vvalue)作用:将指定的键与值放入H......
  • 作物与杂草的智能识别,基于YOLOv8全系列参数模型【n/s/m/lx/】开发构建田间低头作物杂
    一、背景田间杂草的有效管理是现代农业生产中面临的重要挑战之一。杂草不仅竞争作物的养分、水分和阳光,还可能成为害虫和病原体的寄主,从而降低农作物的产量和品质。因此,开发高效、精确的杂草检测和管理系统对于提高农业生产效率、降低化学除草剂的使用以及保护环境具有重要......
  • 基于Java+Springboot+Vue开发的健身房管理系统
    项目简介该项目是基于Java+Springboot+Vue开发的健身房管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的健身房管理系统项目,大学生可以在实践中学习和提升......
  • 前端开发设计模式——命令模式
    目录一、命令模式的定义和特点1.定义:         2. 特点:二、命令模式的结构与原理1.结构:2.原理:三、命令模式的实现方式1.定义接口命令:2.创建具体的命令类:3.定义接收者:4.创建调用者:四、命令模式的使用场景1.界面按钮的点击操作:    1.1 ......
  • Java毕设项目案例实战II基于Spring Boot的科研项目验收管理系统(开发文档+数据库+源码)
    目录一、前言二、技术介绍三、系统实现四、论文参考五、核心代码六、源码获取全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末一、前言随着科研活动的日益增多,科研项目验收作为......
  • 一个标准java程序的创建和使用
    创建1.创建一个记事本,在记事本中写入JAVA代码2.另存为一个后缀为.java的文件,注意,文件名要与类名相同,且存储为ANSI文件 3.点击右键,从终端打开,然后按照如下图方法运行(cat查看文件内容) 命名规范:1.大驼峰:类名2.小驼峰:变量名,方法名,文件名,文件夹名3.全部大写:常量名字命......
  • Java毕设项目案例实战II基于Spring Boot的校园资产管理系统(开发文档+数据库+源码)
    目录一、前言二、技术介绍三、系统实现四、论文参考五、核心代码六、源码获取全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末一、前言在信息化技术日益普及的今天,高效、智能的......
  • JAVA基础知识点
    C/C++速度快JAVA大型web开发,手机端安卓(JAVA是HTML的扩展)C# 中小型Web,桌面程序开发SHELL,VB操作指令Python数字处理,中小型网站PHP中小型网站Arrays.toString(args)对于importjava.util具有依赖作用JAVA特点:1)简单性//语法相较C更简易2)面向对象 3)分......