本博文为《编写高质量代码—改善Java程序的151个建议》一书的阅读笔记。该书从很多方面给予了编写高质量代码的宝贵经验。而且该书应该是那种开发经验越丰富,体会越深的书籍。在阅读过程中,从该书中收获良多,这里主要作下书籍笔记,有体会的地方加点自己的想法。受限于知识水平,部分内容还没能深刻体会,所以更多更好的内容和具体实例还需要从书中去找寻。
一、性能考虑,数组是首选
在Java中数组虽然没有List、Set、Map这些集合类用起来方便,但是在基本类型处理方面,数组还是占优势的,而且集合类的底层也是通过数组实现的。所以在性能要求高的场景中推荐使用数组而不是集合。
二、若有必要,使用变长数组
Java中的数组是定长的,声明后就不可以改变长度,在使用中非常不方便。但是我们可以使用Arrays.copyOf实现数组动态扩容,这样既保证了效率,也提高了可用性。其实集合类的动态扩容也是同理。
三、警惕数组的浅拷贝
Arrays.copyOf方法产生的数组是一个浅拷贝,与序列化的浅拷贝、数组的clone方法、集合的clone方法一样都是浅拷贝:基本类型拷贝值,其他则拷贝引用。因此拷贝对象引用的值的修改也会影响被拷贝的对象的值,因为引用的是同一个地址。
四、在明确的场景下,为集合指定初始容量
集合类可以支持动态扩展长度,使用很方便,不过需要注意的是集合类实际存储使用的是数组,动态扩容也是通过Arrays.copyOf进行的。执行add操作时若默认长度不够时,会将集合的长度增加一定的倍数或长度(比如ArrayList会增加1.5倍),此时在数据量较大时进行拷贝会非常耗资源,效率也很低。
出于性能及资源使用考虑,在集合初始容量已知时,要直接初始为对应长度;在集合初始容量大概知道范围时,可以初始一个比最大值多一点的长度。
五、避开基本类型数组转换列表陷阱
书中举了一个非常好的例子,如下代码
int [] data = {1,2,3,3}; System.out.println(Arrays.asList(data).size());
结果打印出的结果却只有一条,因为asList方法的参数为泛型参数,而基本类型不能作为泛型参数,而int数组是一个对象,同时也是可以泛型化的,所以asList(data)最后实际是把数组对象转换成列表了,结果打印就是1条。
所以一定要注意基本数据类型数组不能做为asList的输入参数,否则会引起程序逻辑混乱。
六、asList方法产生的List对象不可更改
Arrays.asList方法产生的List对象为Arrays类中的静态内部类ArrayList,其修改内容的方法(add、remove)是继承自父类的,而父类的方法仅仅是抛出异常,所以一定要注意asList产生的不可更改,不然会抛异常。
七、不同的列表选用不同的遍历算法
对于支持随机存储(实现RandomAccess接口)的列表,使用下标遍历要比使用foreach遍历快些,在数据量大时尤为明显。而对于顺序存储的列表(例如LinkedList)此时使用foreach又比使用下标遍历效率高些。
具体原因与遍历的实现代码有关,foreach是通过iterator进行遍历的,可以这么理解随机遍历的列表本来就希望下标访问,所以下标访问更快。而有序列表是有顺序的,所以通过foreach一个个迭代效率更高。当然实际原因是实现逻辑的问题。
八、频繁插入和删除时使用LinkedList
这个在数据结构里面肯定提到过,ArrayList这种随机列表随机存取效率高,而LinkedList这种有序列表插入和删除效率更高。即对于列表增、删操作多的应该选用LinkedList,而对于列表修改多的应该选用ArrayList。
九、判断列表相等时只用关心集合是否相等
集合元素进行相等判断(equals)时,可能是不同的集合类型,但是只要集合里面的元素相等则两个集合相等。
十、子列表只是原列表的一个视图
subList产生的列表只是一个视图,所有列表的改动都会直接作用于原列表上。
十一、生成子列表后不要再操作原列表
通过subList生成子列表后,如果再操作原列表会导致subList产生的列表调用size方法时抛出异常。对于子列表,因为视图是动态生成的,生成子列表后再操作原列表,必须导致视图的不稳定性,所以生成子列表后,最好是通过Collections.unmodifiableList方法设置列表为只读状态,这样就能避免错误的发生。
十二、不推荐使用binarySearch对列表进行检索
对一个列表进行检索时,使用的最多的是indexOf方法,该方法是通过遍历进行查找的;Collections类还提供一个binarySearch方法进行检索,该方法是通过二分查找法进行查找的,但是二分查找法有一个前提需要注意,就是列表必须是有序的,不然查找的结果不准确。 因此对于有序列表,binarySearch方法可以优先考虑,而对于无序列表不推荐使用。
十三、集合中的元素必须做到compareTo与equals同步
如果对象实现了compareTo方法就应该覆写equals方法,确保两者同步,不然可能产生逻辑混乱。
十四、集合运算时使用更优雅的方式
例如求并集可以直接使用list1.addAll(list2);求交集可以直接使用list1.retainAll(list2);求差集(属于A但不属于B的集合叫做A与B的差集);求不重复的集合(A与B不重复的集合为A与B的并集去掉一份重复的A与B的交集,如果交集有的话)可以先删后加:list2.remove(list1),list1.addAll(list2)
十五、多线程使用Vector或HashTable
Vector是ArrayList的多线程版本,HashTable是HashMap的多线程版本。在多线程环境下更适用。
相关推荐
Java的集合框架是Java编程中不可或缺的一部分,它提供了一种高效管理对象的方式,包括存储、检索、遍历和操作对象的集合。集合框架的核心接口包括`...理解并熟练掌握这些概念,对于编写高质量的Java代码至关重要。
对于单元测试,JDK6内置了`junit.jar`,支持JUnit4,这是一种流行的测试框架,可以帮助开发者编写和执行测试用例,确保代码质量。 最后,JDK6的文档生成工具`javadoc`能够自动生成API文档,方便开发者理解和使用...
理解作用域对于避免变量冲突和提升代码质量有很大帮助。 - 闭包:闭包是一种特殊的作用域现象,可以访问并操作外部函数的变量,常用于实现私有变量和记忆化等功能。 5. **事件与DOM操作** - 事件处理:JavaScript...
Matplotlib是一个2D绘图库,可以用来绘制高质量的图形和图像,适合于数据可视化。 知识点六:快速排序算法的Python实现 快速排序是一种高效的排序算法,通过选择一个基准元素,将数组分为两个子数组,一个包含所有...
学习笔记源代码1-5.7z这个压缩包包含了作者在阅读和实践这本书籍内容时所编写的代码示例,覆盖了从第一天到第五天的学习内容。这些源代码是读者深入理解和掌握Python在数学应用中的强大功能的宝贵资源。 1. **...
理解如何定义和使用泛型类、接口和方法,是编写高质量Java代码的关键。 9. **枚举与内部类**:枚举是Java中的一种特殊类,用于定义一组相关的常量,而内部类则允许在一个类的内部定义另一个类,提供了更灵活的封装...
通过遵循这些详细的C++代码规范,开发者可以编写出更加高效、可靠且易于维护的代码,同时也有助于团队协作和代码共享。Google的C++风格指南不仅是技术上的指导,更是对软件工程最佳实践的深入探索。
笔记可能包含了敏捷开发方法(如Scrum或Kanban)、版本控制(Git的使用)、持续集成/持续部署(CI/CD)流程,以及如何编写高质量的代码和测试用例。 操作系统原理也是开发者需要了解的。进程与线程的区别、内存管理...
【黑马笔记 PHP】标签表明这是一份由知名在线教育平台黑马程序员提供的学习资料,因此其内容质量和实用性相对较高,适合初学者和有一定经验的开发者参考。 综上所述,这份【PHP自学笔记】提供了一条全面的学习路径...
以上知识点是Java编程中的基础且核心的部分,理解和掌握它们对于编写高质量的Java代码至关重要。学习这些内容可以帮助开发者更好地设计和实现复杂的应用程序,提升编程效率。通过深入研究和实践,你可以将这些理论...
Java JDK 5.0是Java发展历程中的一个重要里程碑,它引入了许多创新特性,为开发者提供了更加高效和便捷的编程环境。...通过深入学习和实践,开发者可以更好地利用Java 5.0的特性,提高编程效率,编写出更高质量的代码。
同时,会强调版本控制工具(如Git)的使用,以及编写高质量代码的标准和规范。 5. **实践项目**:为了巩固理论知识,笔记可能包含了一些实际项目或练习,让学生有机会将所学应用到实践中。这可能包括创建简单的应用...
4. **准备比赛**:了解比赛规则,学习如何在规定时间内完成高质量的代码,提高比赛策略和时间管理能力。 5. **社区互动**:可能包含了一些讨论或交流的链接,可以与其他学习者或专家互动,共同进步。 总之,...
该文档是Java就业班第一阶段的学习笔记,涉及Java基础知识和对数据库操作的学习。这部分内容对Java初学者非常重要,涵盖了注释、异常处理、数组、常用类、集合、IO操作、线程以及MySQL数据库操作等初级知识点。下面...
以上这些知识点构成了Java编程的基础,理解和掌握它们对于编写高质量的Java代码至关重要。在实际编程中,还需要结合面向对象设计原则、异常处理、多线程、集合框架等更高级的概念来进一步提升编程能力。
例如,使用GDB进行调试,以及编写测试用例来确保代码质量。 此外,作者提供了这本书的更新信息和联系方式,以及版权声明。本书可以在不侵犯作者个人权利的前提下自由散播,下载地址为***,可通过电子邮件***与作者...
12. **单元测试**:JUnit是Java常用的单元测试框架,学习如何编写测试用例,进行断言和异常测试,保证代码质量。 这些知识点构成了Java SE(标准版)的基础,通过"java-se-master"这个项目,你可以系统地学习和实践...
Java SE(标准版)是Java开发平台的核心,用于构建桌面应用程序和服务器端应用。这份"javase 学习笔记(李巍老师)"涵盖了Java...在实际编程中,还需要不断学习和磨练,以提升解决问题的能力和编写高质量代码的技巧。
此外,区分赋值运算符“=”和相等运算符“==”,并在if语句中使用大括号包裹所有的代码块,即使只有一行代码也不例外,这些都是提高代码质量和可维护性的良好实践。 ### 5. 函数 函数是C++编程的基本构建块之一,...
这些关键字的理解和正确使用,对于编写高质量的Java代码至关重要。 通过阅读这份笔记,你可以系统地学习和复习Java的基础知识,加深对关键字的理解,从而提升编程技能。无论是初学者想要入门,还是专业人士希望巩固...