Java代码优化小结(二)
(21)将常量声明为static final,并以大写命名
这样在编译期间就可以把这些内容放入常量池中,避免运行期间计算生成常量的值。另外,将常量的名字以大写命名也可以方便区分出常量与变量
(22)不要创建一些不使用的对象,不要导入一些不使用的类
这毫无意义,如果代码中出现”The value of the local variable i is not used”、”The import java.util is never used”,那么请删除这些无用的内容
(23)程序运行过程中避免使用反射
反射是Java提供给用户一个很强大的功能,功能强大往往意味着效率不高。不建议在程序运行过程中使用尤其是频繁使用反射机制,特别是Method的invoke方法,如果确实有必要,一种建议性的做法是将那些需要通过反射加载的类在项目启动的时候通过反射实例化出一个对象并放入内存—-用户只关心和对端交互的时候获取最快的响应速度,并不关心对端的项目启动花多久时间。
(24)使用数据库连接池和线程池
这两个池都是用于重用对象的,前者可以避免频繁地打开和关闭连接,后者可以避免频繁地创建和销毁线程。
(25)使用带缓冲的输入输出流进行IO操作
带缓冲的输入输出流,即BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,这可以极大地提升IO效率。
(26)顺序插入和随机访问比较多的场景使用ArrayList,元素删除和中间插入比较多的场景使用LinkedList
这个,理解ArrayList和LinkedList的原理就知道了。
(27)不要让public方法中有太多的形参
public方法即对外提供的方法,如果给这些方法太多形参的话主要有两点坏处:
违反了面向对象的编程思想,Java讲求一切都是对象,太多的形参,和面向对象的编程思想并不契合
参数太多势必导致方法调用的出错概率增加
至于这个”太多”指的是多少个,3、4个吧。比如我们用JDBC写一个insertStudentInfo方法,有10个学生信息字段要插如Student表中,可以把这10个参数封装在一个实体类中,作为insert方法的形参。
(28)字符串变量和字符串常量equals的时候将字符串常量写在前面
这是一个比较常见的小技巧了,如果有以下代码:
- String str = "123" ;
- if (str.equals( "123" )){
- ...
- }
- //建议修改为:
- String str = "123" ;
- if ( "123" .equals(str)){
- ...
- }
这么做主要是可以避免空指针异常。
(29)请知道,在java中if (i == 1)和if (1 == i)是没有区别的,但从阅读习惯上讲,建议使用前者
(30)不要对数组使用toString()方法
看一下对数组使用toString()打印出来的是什么:
- public static void main(String[] args){
- int [] is = new int []{ 1 , 2 , 3 };
- System.out.println(is.toString());
- }
- //结果是:[I @18a992f
本意是想打印出数组内容,却有可能因为数组引用is为空而导致空指针异常。不过虽然对数组toString()没有意义,但是对集合toString()是可以打印出集合里面的内容的,因为集合的父类AbstractCollections<E>重写了Object的toString()方法。
(31)不要对超出范围的基本数据类型做向下强制转型
这绝不会得到想要的结果:
- public static void main(String[] args){
- long l = 12345678901234L;
- int i = ( int )l;
- System.out.println(i);
- }
我们可能期望得到其中的某几位,但是结果却是:1942892530
转换成二进制:Java中long是8个字节64位的,int型数据是4个字节32位的,从低位取出long转换的这串二进制数据的前32位。
得到两个结论:
- 1、整型默认的数据类型是int,long l = 12345678901234L,这个数字已经超出了int的范围了,所以最后有一个L,表示这是一个long型数。顺便,浮点型的默认类型是double,所以定义float的时候要写成”"float f = 3.5f”
- 2、接下来再写一句”int ii = l + i;”会报错,因为long + int是一个long,不能赋值给int。
(32)公用的集合类中不使用的数据一定要及时remove掉
如果一个集合类是公用的(也就是说不是方法里面的属性),那么这个集合里面的元素是不会自动释放的,因为始终有引用指向它们。所以,如果公用集合里面的某些数据不使用而不去remove掉它们,那么将会造成这个公用集合不断增大,使得系统有内存泄露的隐患。
(33)把一个基本数据类型转为字符串,基本数据类型.toString()是最快的方式、String.valueOf(数据)次之、数据+”"最慢
遇到把一个基本数据类型转为String的时候,优先考虑使用toString()方法。至于为什么,很简单:
String.valueOf()方法底层调用了Integer.toString()方法,但是会在调用前做空判断
Integer.toString()方法就不说了,直接调用了
i + “”底层使用了StringBuilder实现,先用append方法拼接,再用toString()方法获取字符串
(34)使用最有效率的方式去遍历Map
遍历Map的方式有很多,通常场景下我们需要的是遍历Map中的Key和Value,那么推荐使用的、效率最高的方式是:
- public static void main(String[] args){
- HashMap<String, String> hm = new HashMap<String, String>();
- hm.put( "111" , "222" );
- Set<Map.Entry<String, String>> entrySet = hm.entrySet();
- Iterator<Map.Entry<String, String>> iter = entrySet.iterator();
- while (iter.hasNext()){
- Map.Entry<String, String> entry = iter.next();
- System.out.println(entry.getKey() + " " + entry.getValue());
- }
- }
如果你只是想遍历一下这个Map的key值,那用”Set<String> keySet = hm.keySet();”会比较合适一些。
补充:
下面是用keySet()和enrtySet()测试两者遍历集合效率的测代码
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- /**
- * @Author: jackpotHan
- * @Date: 2018/7/18 16:53
- * @Description:
- */
- public class MapTest {
- public static void main(String[] args) {
- Map<String,String> keySetMap = new HashMap<>();
- Map<String,String> entrySetMap = new HashMap<>();
- for (int i = 0; i < 1000000; i++) {
- keySetMap.put("" + i, "keySet");
- }
- for (int j = 0; j < 1000000; j++) {
- entrySetMap.put("" + j, "entrySet");
- }
- Long startTime1 = System.currentTimeMillis();
- Iterator<String> keySetIterator = keySetMap.keySet().iterator();
- while (keySetIterator.hasNext()) {
- String key = keySetIterator.next();
- String value = keySetMap.get(key);
- System.out.println(value);
- }
- Long keySetTime = System.currentTimeMillis() - startTime1;
- long startTime2 = System.currentTimeMillis();
- Iterator<Map.Entry<String, String>> entryKeyIterator = entrySetMap
- .entrySet().iterator();
- while (entryKeyIterator.hasNext()) {
- Map.Entry<String, String> e = entryKeyIterator.next();
- System.out.println(e.getValue());
- }
- Long entryTime = System.currentTimeMillis() - startTime2;
- System.out.println("keySetSpentTime:" + keySetTime);
- System.out.println("enrtySetSpentTime:" + entryTime);
- }
- }
- //两者耗时对比:
- // keySetSpentTime:6509
- // enrtySetSpentTime:6477
Java代码优化小结(二)的更多相关文章
- Java代码优化小结(三)
(35)对资源的close()建议分开操作虽然有些麻烦,却能避免资源泄露.我们想,如果没有修改过的代码,万一XXX.close()抛异常了,那么就进入了catch块中了,YYY.close()不会执行 ...
- Java代码优化小结(一)
(1)尽量指定类.方法的final修饰符 带有final修饰符的类是不可派生的.在Java核心API中,有许多应用final的例子,例如java.lang.String,整个类都是final的.为类指 ...
- Java 基础--小结
Java 基础--小结 java基础 Java源程序(.java文件)——>java字节码文件(.class文件)——>由解释执行器(java.exe)将字节码文件加载到java虚拟机( ...
- 关于Java代码优化的44条建议!
关于Java代码优化的N条建议! 本文是作者:五月的仓颉 结合自己的工作和平时学习的体验重新谈一下为什么要进行代码优化.在修改之前,作者的说法是这样的: 就像鲸鱼吃虾米一样,也许吃一个两个虾米对于鲸鱼 ...
- Java代码优化的30个小技巧
前言 我之前写过两篇关于优化相关的问题:<聊聊sql优化的15个小技巧>和<聊聊接口性能优化的11个小技巧>,发表之后,在全网受到广大网友的好评.阅读量和点赞率都很高,说明了这 ...
- Java开发学习(二十四)----SpringMVC设置请求映射路径
一.环境准备 创建一个Web的Maven项目 参考Java开发学习(二十三)----SpringMVC入门案例.工作流程解析及设置bean加载控制中环境准备 pom.xml添加Spring依赖 < ...
- Java开发学习(二十五)----使用PostMan完成不同类型参数传递
一.请求参数 请求路径设置好后,只要确保页面发送请求地址和后台Controller类中配置的路径一致,就可以接收到前端的请求,接收到请求后,如何接收页面传递的参数? 关于请求参数的传递与接收是和请求方 ...
- Java开发学习(二十七)----SpringMVC之Rest风格解析及快速开发
一.REST简介 REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格 当我们想表示一个网络资源的时候,可以使用两种方式: 传统风格资源描 ...
- 实战Java虚拟机之二“虚拟机的工作模式”
今天开始实战Java虚拟机之二:“虚拟机的工作模式”. 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实 ...
随机推荐
- Linux基础三:linux目录结构和目录文件的浏览、管理及维护
目录文件的浏览.管理及维护(一) 1.Linux文件系统的层次结构 1)Linux文件系统的树状结构:在Linux或UNIX操作系统中,所有的文件和目录都被组织成一个以根节点开始的倒置的树状结构. 2 ...
- Java 获取窗口的宽、高
创建一个新窗口,通过getSize()获取这个窗口的宽.高. import javax.swing.JFrame; public class WindowInTheMiddle extends JFr ...
- centos之mysql安装配置使用
安装: 这里只安装得时mysql5.1,如果想安装5.6,看这里http://www.cnblogs.com/xuange306/p/8243859.html yum install -y mysq ...
- Just Oj 2017C语言程序设计竞赛高级组A: 求近似值(矩阵快速幂)
A: 求近似值 时间限制: 1 s 内存限制: 128 MB 提交 我的状态 题目描述 求⌊(5–√+6–√)2n⌋⌊(5+6)2n⌋%9932017. 例如:n=1,(5–√+6–√)2( ...
- 指定的参数已超出有效值的范围。参数名:sit ,先仔细看看错误和我的一样不一样
控制面板>程序>
- Vue.js货币格式化函数
函数: const digitsRE = /(\d{3})(?=\d)/g export function currency (value, currency, decimals) { value = ...
- nunit单元测试详解
在粗略看了代码后,下面就详细说明相应的测试标记(属性)的用法. [TestFixture(arguments)]属性标记类为测试类,若没有填写参数,则测试类必须含有无参构造函数,否则需要相应的有参构造 ...
- 【BZOJ4712】洪水
题解: 注意题目说了每个点的权值只能增加 每个点的dp方程比较简单 min(v[i],sum[i]) 那么我们考虑如果v[i]增加那么上面使用sum[i]的会带来影响 暴力的做就是一个个往上查然后修改 ...
- Docker Client (another java docker client api)
前一篇提到了docker-java,这里介绍另一个docker client 库,Docker Client 版本兼容 兼容17.03.1~ce - 17.12.1~ce (点 [here][1]查看 ...
- Linux批量清空当前目录中的日志文件
在Linux中,有时需要批量清空当前目录中的日志文件,同时还要保留日志文件. 其实一行shell命令就可以搞定,一起来看看吧. 在当前目录下,键入如下命令: for i in `find . -nam ...