Java优雅编码 让代码性能更高

本文介绍了多个提升Java代码性能的实践方法,如使用`entrySet()`迭代Map,利用`isEmpty()`检测空集合,避免集合对象传给自己,初始化集合时指定大小,字符串拼接使用`StringBuilder`,根据数据结构选择访问方式,使用Set优化`contains`调用,直接赋值常量,定义静态常量,避免自动装箱拆箱,减少不必要的方法封装,利用移位运算替代乘除,以及在多线程环境中使用线程安全类等。通过遵循这些最佳实践,可以使Java代码运行得更加高效和优雅。
摘要由CSDN通过智能技术生成

Java优雅编码
让代码性能更高

  1. 需要 Map 的主键和取值时,应该迭代 entrySet()
  2. 应该使用Collection.isEmpty()检测空
  3. 不要把集合对象传给自己
  4. 集合初始化尽量指定大小
  5. 字符串拼接使用 StringBuilder
  6. 判断链表还是数组
  7. 频繁调用 Collection.contains 方法请使用 Set
  8. 直接赋值常量值,禁止声明新对象
  9. 当成员变量值无需改变时,尽量定义为静态常量
  10. 尽量使用基本数据类型,避免自动装箱和拆箱
  11. 如果变量的初值会被覆盖,就没有必要给变量赋初值
  12. 尽量使用函数内的基本类型临时变量
  13. 尽量不要在循环体外定义变量
  14. 不可变的静态常量,尽量使用非线程安全类
  15. 尽量避免定义不必要的子类
  16. 尽量指定类的final修饰符
  17. 把跟类成员变量无关的方法声明成静态方法
  18. 尽量使用基本数据类型作为方法参数类型,避免不必要的装箱、拆箱和空指针判断
  19. 协议方法参数值非空,避免不必要的空指针判断
  20. 尽量避免不必要的函数封装
  21. 尽量减少方法的重复调用
  22. 尽量使用移位来代替正整数乘除
  23. 尽量不在条件表达式中使用!取反
  24. 对于多常量选择分支,尽量使用switch语句而不是if-else语句
  25. 尽量不要使用正则表达式匹配
  26. 不要使用循环拷贝数组,尽量使用System.arraycopy拷贝数组
  27. 集合转化为类型T数组时,尽量传入空数组T[0]
  28. 不要使用循环拷贝集合,尽量使用JDK提供的方法拷贝集合
  29. 尽量重复使用同一缓冲区
  30. 尽量使用缓冲流减少IO操作
  31. 在单线程中,尽量使用非线程安全类
  32. 在多线程中,尽量使用线程安全类
  33. 尽量减少同步代码块范围
  34. 尽量使用线程池减少线程开销
    让代码更优雅
  35. 长整型常量后添加大写 L
  36. 不要使用魔法值
  37. 不要使用集合实现来赋值静态成员变量
  38. 建议使用 try-with-resources 语句
  39. 删除未使用的方法、参数、变量
  40. 公有静态常量应该通过类访问
  41. 使用String.valueOf(value)代替""+value
  42. 过时代码添加 @Deprecated 注解
  43. 尽量避免在循环中捕获异常
    让代码远离 bug
  44. 禁止使用构造方法 BigDecimal(double)
  45. 返回空数组和空集合而不是 null
  46. 优先使用常量或确定值来调用 equals 方法
  47. 枚举的属性字段必须是私有不可变
  48. 小心String.split(String regex)
    让代码性能更高
  49. 需要 Map 的主键和取值时,应该迭代 entrySet()
    反例:

Map<String, String> map = …;
for (String key : map.keySet()) {
String value = map.get(key);

}
1
2
3
4
5
正例

Map<String, String> map = …;
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();

}
1
2
3
4
5
6
2. 应该使用Collection.isEmpty()检测空
反例:

if (collection.size() == 0) {

}
1
2
3
正例:

if (collection.isEmpty()) {

}
1
2
3
如果需要还需要检测 null ,可采用CollectionUtils.isEmpty(collection)和CollectionUtils.isNotEmpty(collection)。

  1. 不要把集合对象传给自己
    反例:

List list = new ArrayList<>();
list.add(“Hello”);
list.add(“World”);
if (list.containsAll(list)) { // 无意义,总是返回true

}
list.removeAll(list); // 性能差, 直接使用clear()
1
2
3
4
5
6
7
4. 集合初始化尽量指定大小
Java集合初始化时都会指定一个默认大小,当默认大小不再满足数据需求时就会扩容,每次扩容的时间复杂度有可能是O(n)
反例:

List userDOList = …;
Set userSet = new HashSet<>();
Map<Long, UserDO> userMap = new HashMap<>();
List userList = new ArrayList<>();
for (UserDO userDO : userDOList) {
userSet.add(userDO.getId());
userMap.put(userDO.getId(), userDO);
userList.add(transUser(userDO));
}
1
2
3
4
5
6
7
8
9
正例:

List userDOList = …;
int userSize = userDOList.size();
Set userSet = new HashSet<>(userSize);
Map<Long, UserDO> userMap = new HashMap<>((int) Math.ceil(userSize * 4.0 / 3));
List userList = new ArrayList<>(userSize);
for (UserDO userDO : userDOList) {
userSet.add(userDO.getId());
userMap.put(userDO.getId(), userDO);
userList.add(transUser(userDO));
}
1
2
3
4
5
6
7
8
9
10
5. 字符串拼接使用 StringBuilder
反例:

String s = “”;
for (int i = 0; i < 10; i++) {
s += i;
}
1
2
3
4
正例:

String a = “a”;
String b = “b”;
String c = “c”;
String s = a + b + c; // 没问题,java编译器会进行优化
StringBuilder sb = new StringBuilder(50); //尽量设置初始化大小
for (int i = 0; i < 10; i++) {
sb.append(i);
}
1
2
3
4
5
6
7
8
6. 判断链表还是数组
正例:

// 调用别人的服务获取到list
List list = otherService.getList();
if (list instanceof RandomAccess) {
// 内部数组实现,可以随机访问
System.out.println(list.get(list.size() - 1));
} else {
// 内部可能是链表实现,随机访问效率低
}
1
2
3
4
5
6
7
8
7. 频繁调用 Collection.contains 方法请使用 Set
反例:

ArrayList list = otherService.getList();
for (int i = 0; i <= Integer.MAX_VALUE; i++) {
// 时间复杂度O(n)
list.contains(i);
}
1
2
3
4
5
正例:

ArrayList list = otherService.getList();
Set set = new HashSet(list);
for (int i = 0; i <= Integer.MAX_VALUE; i++) {
// 时间复杂度O(1)
set.contains(i);
}
1
2
3
4
5
6
8. 直接赋值常量值,禁止声明新对象
直接赋值常量值,只是创建了一个对象引用,而这个对象引用指向常量值。
反例:

Long i = new Long(1L);
String s = new String(“abc”);
1
2
正例:

Long i = 1L;
String s = “abc”;
1
2
9. 当成员变量值无需改变时,尽量定义为静态常量
在类的每个对象实例中,每个成员变量都有一份副本,而成员静态常量只有一份实例
反例:

public class HttpConnection {
private final long timeout = 5L;

}
1
2
3
4
正例:

public class HttpConnection {
private static final long TIMEOUT = 5L;

}
1
2
3
4
5
10. 尽量使用基本数据类型,避免自动装箱和拆箱
装箱和拆箱都是需要CPU和内存资源的,所以应尽量避免使用自动装箱和拆箱
反例:

Integer sum = 0;
int[] values = …;
for (int value : values) {
sum += value; // 相当于result = Integer.valueOf(result.intValue() + value);
}
1
2
3
4
5<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值