编写高质量代码:改善Java程序的151个建议 --[52~64]
编写高质量代码:改善Java程序的151个建议 --[52~64]
推荐使用String直接量赋值
Java为了避免在一个系统中大量产生String对象(为什么会大量产生,因为String字符串是程序中最经常使用的类型),于是就设计了一个字符串池(也叫作字符串常量池,String pool或String Constant Pool或String Literal Pool),在字符串池中容纳的都是String字符串对象,它的创建机制是这样的:创建一个字符串时,首先检查池中是否有字面值相等的字符串,如果有,则不再创建,直接返回池中该对象的引用,若没有则创建之,然后放到池中,并返回新建对象的引用,这个池和我们平常说的池非常接近。对于此例子来说,就是创建第一个"詹姆斯"字符串时,先检查字符串池中有没有该对象,发现没有,于是就创建了"詹姆斯"这个字符串并放到池中,待创建str2字符串时,由于池中已经有了该字符串,于是就直接返回了该对象的引用,此时,str1和str2指向的是同一个地址,所以使用"=="来判断那当然是相等的了。
public class Client58 {
public static void main(String[] args) {
//建议
String str1 = "詹姆斯";
//建议
String str2 = "詹姆斯";
//不建议,直接声明一个String对象是不检查字符串池的,也不会把对象放到字符串池中
String str3 = new String("詹姆斯");
String str4 = str3.intern();
// 两个直接量是否相等
System.out.println(str1 == str2);
// 直接量和对象是否相等
System.out.println(str1 == str3);
// 经过intern处理后的对象与直接量是否相等,
//intern会检查当前对象在对象池中是否存在字面值相同的引用对象,如果有则返回池中的对象,如果没有则放置到对象池中,并返回当前对象。
System.out.println(str1 == str4);
}
}
正确使用String、StringBuffer、StringBuilder
使用String类的场景:在字符串不经常变化的场景中可以使用String类,例如常量的声明、少量的变量运算等;
使用StringBuffer的场景:在频繁进行字符串的运算(如拼接、替换、删除等),并且运行在多线程的环境中,则可以考虑使用StringBuffer,例如XML解析、HTTP参数解析和封装等;
使用StringBuilder的场景:在频繁进行字符串的运算(如拼接、替换、删除等),并且运行在单线程的环境中,则可以考虑使用StringBuilder,如SQL语句的拼接,JSON封装等。
性能对比:
StringBuffer和StringBuilder基本相同,都是可变字符序列,不同点是:StringBuffer是线程安全的,StringBuilder是线程不安全的,翻翻两者的源代码,就会发现在StringBuffer的方法前都有关键字syschronized,这也是StringBuilder在性能上远远低于StringBuffer的原因。
在性能方面,由于String类的操作都是产生String的对象,而StringBuilder和StringBuffer只是一个字符数组的再扩容而已,所以String类的操作要远慢于StringBuffer 和 StringBuilder。
强烈建议使用UTF编码
使用Collator类排序汉字
如果排序对象是经常使用的汉字,使用Collator类排序完全可以满足我们的要求,毕竟GB2312已经包含了大部分的汉字,如果需要严格排序,则要使用一些开源项目来自己实现了,比如pinyin4j可以把汉字转换为拼音,然后我们自己来实现排序算法,不过此时你会发现要考虑的诸如算法、同音字、多音字等众多问题。
import java.text.Collator;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;
public class CollatorDemo {
public static void main(String[] args) {
String[] strs = { "张三(Z)", "李四(L)", "王五(W)" };
//定义一个中文排序器
Comparator c = Collator.getInstance(Locale.CHINA);
Arrays.sort(strs,c);
int i = 0;
for (String str : strs) {
System.out.println((++i) + "、" + str);
}
}
}
结果:
1、李四(L)
2、王五(W)
3、张三(Z)
性能要求较高的场景中使用数组代替集合
对基本类型进行求和运算时,数组的效率是集合的10倍。
//对数组求和
public static int sum(int datas[]) {
int sum = 0;
for (int i = 0; i < datas.length; i++) {
sum += datas[i];
}
return sum;
}
// 对列表求和计算
public static int sum(List<Integer> datas) {
int sum = 0;
for (int i = 0; i < datas.size(); i++) {
sum += datas.get(i);
}
return sum;
}
基本类型是在栈内存中操作的,而对象是堆内存中操作的,栈内存的特点是:速度快,容量小;堆内存的特点是:速度慢,容量大(从性能上讲,基本类型的处理占优势)。其次,在进行求和运算时(或者其它遍历计算)时要做拆箱动作,因此无谓的性能消耗也就产生了。
若有必要,使用变长数组
public static <T> T[] expandCapacity(T[] datas, int newLen) {
// 不能是负值
newLen = newLen < 0 ? 0 : newLen;
// 生成一个新数组,并拷贝原值
return Arrays.copyOf(datas, newLen);
}
public static void main(String[] args) {
//一个班级最多容纳60个学生
Stu [] stuNums= new Stu[60];
//stuNums初始化......
//偶尔一个班级可以容纳80人,数组加长
stuNums=expandCapacity(stuNums,80);
/* 重新初始化超过限额的20人...... */
}
在明确的场景下,为集合指定初始容量
ArrayList():默认构造函数,提供初始容量为10的空列表。
ArrayList(int initialCapacity):构造一个具有指定初始容量的空列表。
ArrayList(Collection<? extends E> c):构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
从这里我们可以看出,如果不设置初始容量,系统会按照1.5倍的规则扩容,每次扩容都是一次数组的拷贝,如果数据量大,这样的拷贝会非常消耗资源,而且效率非常低下。所以,我们如果知道一个ArrayList的可能长度,然后对ArrayList设置一个初始容量则可以显著提高系统性能。
编写高质量代码:改善Java程序的151个建议 --[52~64]的更多相关文章
- 博友的 编写高质量代码 改善java程序的151个建议
编写高质量代码 改善java程序的151个建议 http://www.cnblogs.com/selene/category/876189.html
- 编写高质量代码改善java程序的151个建议——导航开篇
2014-05-16 09:08 by Jeff Li 前言 系列文章:[传送门] 下个星期度过这几天的奋战,会抓紧java的进阶学习.听过一句话,大哥说过,你一个月前的代码去看下,慘不忍睹是吧.确实 ...
- 编写高质量代码改善java程序的151个建议——[1-3]基础?亦是基础
原创地址: http://www.cnblogs.com/Alandre/ (泥沙砖瓦浆木匠),需要转载的,保留下! Thanks The reasonable man adapts himse ...
- 编写高质量代码:改善Java程序的151个建议 --[117~128]
编写高质量代码:改善Java程序的151个建议 --[117~128] Thread 不推荐覆写start方法 先看下Thread源码: public synchronized void start( ...
- 编写高质量代码:改善Java程序的151个建议 --[106~117]
编写高质量代码:改善Java程序的151个建议 --[106~117] 动态代理可以使代理模式更加灵活 interface Subject { // 定义一个方法 public void reques ...
- 编写高质量代码:改善Java程序的151个建议 --[78~92]
编写高质量代码:改善Java程序的151个建议 --[78~92] HashMap中的hashCode应避免冲突 多线程使用Vector或HashTable Vector是ArrayList的多线程版 ...
- 编写高质量代码:改善Java程序的151个建议 --[65~78]
编写高质量代码:改善Java程序的151个建议 --[65~78] 原始类型数组不能作为asList的输入参数,否则会引起程序逻辑混乱. public class Client65 { public ...
- 编写高质量代码:改善Java程序的151个建议 --[36~51]
编写高质量代码:改善Java程序的151个建议 --[36~51] 工具类不可实例化 工具类的方法和属性都是静态的,不需要生成实例即可访 问,而且JDK也做了很好的处理,由于不希望被初始化,于是就设置 ...
- Github即将破百万的PDF:编写高质量代码改善JAVA程序的151个建议
在通往"Java技术殿堂"的路上,本书将为你指点迷津!内容全部由Java编码的最佳 实践组成,从语法.程序设计和架构.工具和框架.编码风格和编程思想等五大方面,对 Java程序员遇 ...
随机推荐
- Bootstrap知识记录:表格和按钮
基本格式.table3.带边框的表格//给表格增加边框<table class="table table-bordered">4.悬停鼠标//让<tbody> ...
- java代理:静态代理和动态代理
一.Java中有一个设计模式是代理模式 代理模式是常用的Java设计模式,特征是代理类与委托类有相同的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类 ...
- ArrayList性能短板深入分析
ArrayList的数据结构主体是Object[]数组,数组对象在内存的位置是成块成块的. 1.对数组进行非尾部修改,会引发System.arrayCopy()行为.这就需要对后半部要移动的对象进行内 ...
- 老男孩python学习自修第二十三天【多线程】
1. 线程的创建与运行 #!/usr/bin/env python # _*_ coding:UTF-8 _*_ from threading import Thread def foo(param1 ...
- Java使用RabbitMQ之整合Spring(消费者)
依赖包: <!--RabbitMQ集成spring--> <!-- https://mvnrepository.com/artifact/org.springframework.am ...
- 学习 Spring (十五) Advisor
Spring入门篇 学习笔记 advisor 就像一个小的自包含的方面,只有一个 advice 切面自身通过一个 bean 表示,并且必须实现某个 advice 接口,同时 advisor 也可以很好 ...
- 学习 Spring (一) Spring 介绍
Spring入门篇 学习笔记 Spring 是什么 Spring 是一个轻量级的 IoC (控制反转)和 AOP (面向切面)的容器框架 框架与类库的区别 框架一般是封装了逻辑.高内聚的,类库则是松散 ...
- Git要点
前面的话 本文将总结Git要点 版本管理工具 [作用] 1.备份文件 2.记录历史 3.回到过去 4.对比差异 [分类] 1.手动版本控制(又叫人肉VCS) 2.LVCS 本地 3.CVCS 集中式( ...
- 手写事务管理器 也是spring实现事务管理的原理
- 洛谷 P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节. 由于牛棚不太大,FJ通过指定奶牛必须遵 ...