本文共 4743 字,大约阅读时间需要 15 分钟。
目录
1. 尽量使用final修饰符
带有final修饰符的类是不可派生的。在JAVA核心API中,有许多应用final的例子,例如java、lang、String,为String类指定final防止了使用者覆盖length()方法。另外,如果一个类是final的,则该类所有方法都是final的。java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关),此举能够使性能平均提高50%。
如:让访问实例内变量的getter/setter方法变成”final:
简单的getter/setter方法应该被置成final,这会告诉编译器,这个方法不会被重载,所以,可以变成”inlined”,例子
public class Student { private String name; private Integer age;//普通使用 final public String getName() { return name; } final public Integer getAge() { return age; }//优化使用 public String getName() { return name; } public Integer getAge() { return age; }}
2.. 尽量减少对变量的重复计算
如:
for(int i=0;i
- 上面的每次循环都要交计算list.size(),下面的将list.size()首先计算出来放入变量len,避免了多次重复计算
应该改为:
for(int i=0,len=list.size();i
并且在循环中应该避免使用复杂的表达式,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。
3.. 尽量避免不必要的创建
如:
A a = new A();if(i==1){list.add(a);}//应该改为下面的代码,因为上面的是先创建对象,然后再判断是否添加,如果不符合if条件,那么对象也会被创建影响性能if(i==1){A a = new A();list.add(a);}
4. 尽量使用移位来代替’a/b’和’a*b’的操作
“/”和‘*’是一个代价很高的操作,使用移位的操作将会更快和更有效
如:
int num = a / 4;int num = a / 8;//应该改为int num = a >> 2;int num = a >> 3;int num = a * 4;int num = a * 8;//应该改为int num = a << 2;int num = a << 3;
5. 尽量确定StringBuffer的容量
StringBuffer 的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建 StringBuffer的时候指定合适的大小,这样就避免了在容量不够的时候自动增长,以提高性能。无论何时,只要StringBuffer到达它的最大容量,它就不得不创建一个新的对象数组,然后复制旧的对象数组,这会浪费很多时间。所以给StringBuffer设置一个合理的初始化容量值,是很有必要的!
如:
StringBuffer buffer = new StringBuffer(1000);
StringBuffer初始化时,其容量大小(Capacity)为16;其后容量不够时按照9*(2的n次方)来增长。
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。 相同情况下,使用StringBuilder比使用StringBuffer仅能获得10%~15%的性能提升,但却要冒多线程不安全的风险。综合考虑还是建议使用StringBuffer。
public static void main(String[] args) { StringBuffer buffer= new StringBuffer(100); buffer.append(66); buffer.append("我是学生"); System.out.println(buffer); StringBuilder builder=new StringBuilder(100); /** * public StringBuffer append(String s) * 将指定的字符串追加到此字符序列。 */ builder.append(12); builder.append("我是学生1"); builder.append("我是学生2"); builder.append("我是学生3"); System.out.println(builder); /** * public delete(int start, int end), * start:开始的字符串的位置,从0开始,end:结束的字符串的位置 */ builder.delete(0,3); /** * public insert(int offset, object i) * 将参数i的字符串表示形式插入此序列中。 * offset:从什么位置开始插入 */ int i =12; builder.insert(0,i); System.out.println(builder); /** * int length() * 返回长度(字符数),中文和英文都算一个字符 */ System.out.println(builder.length()); /** *String toString() *返回此序列中数据的字符串表示形式。 */ builder.toString().split(""); }
6. 尽量避免使用二维数组
二维数据占用的内存空间比一维数组多得多,大概10倍以上。
7. 尽量避免使用split
除非是必须的,否则应该避免使用split,split由于支持正则表达式,所以效率比较低,如果是频繁的几十,几百万的调用将会耗费大量资源,如果确实需要频繁的调用split,可以考虑使用apache的StringUtils.split(string,char),频繁split的可以缓存结果。
8. ArrayList (线性表)& LinkedList(链表)
一个是线性表,一个是链表,一句话,随机查询尽量使用ArrayList,ArrayList优于LinkedList,LinkedList还要移动指针,添加删除的操作LinkedList优于ArrayList,ArrayList还要移动数据
9. 慎用异常
当创建一个异常时,需要收集一个栈跟踪(stack track),这个栈跟踪用于描述异常是在何处创建的。构建这些栈跟踪时需要为运行时栈做一份快照,正是这一部分开销很大。当需要创建一个 Exception 时,JVM 不得不说:先别动,我想就您现在的样子存一份快照,所以暂时停止入栈和出栈操作。栈跟踪不只包含运行时栈中的一两个元素,而是包含这个栈中的每一个元素。
如果您创建一个 Exception ,就得付出代价,好在捕获异常开销不大,因此可以使用 try-catch 将核心内容包起来。从技术上讲,你甚至可以随意地抛出异常,而不用花费很大的代价。招致性能损失的并不是 throw 操作——尽管在没有预先创建异常的情况下就抛出异常是有点不寻常。真正要花代价的是创建异常,不应该不管三七二十一就抛出异常。异常是为异常的情况而设计的,使用时也应该牢记这一原则
10. SQL语言应尽量使用大写形式
在java+Oracle的应用系统开发中,java中内嵌的SQL语言应尽量使用大写形式,以减少Oracle解析器的解析负担。
11. 不要在循环中使用Try/Catch语句,应把Try/Catch放在循环最外层
12. array(数组)和ArrayList的使用
array 数组效率最高,但容量固定,无法动态改变,ArrayList容量可以动态增长,但牺牲了效率。
为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢?
那么为什么不List list; list=null; list.add(123);?因为list是接口这样使用时错误的
方便以后扩展
List是一个接口,而ArrayList 是一个类。 ArrayList 继承并实现了List。 List list = new ArrayList();这句创建了一个ArrayList的对象后把上溯到了List。此时它是一个List对象了,有些ArrayList有但是List没有的属性和方法,它就不能再用了。而ArrayList list=new ArrayList();创建一对象则保留了ArrayList的所有属性。 为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢? 问题就在于List有多个实现类,如 LinkedList或者Vector等等,现在你用的是ArrayList,也许哪一天你需要换成其它的实现类呢?,这时你只要改变这一行就行了:List list = new LinkedList(); 其它使用了list地方的代码根本不需要改动。假设你开始用 ArrayList alist = new ArrayList(), 这下你有的改了,特别是如果你使用了 ArrayList特有的方法和属性。 如果没有特别需求的话,最好使用List list = new LinkedList(); ,便于程序代码的重构. 这就是面向接口编程的好处。
转载地址:https://mapengsen.blog.csdn.net/article/details/108681630 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!