在Java编程的世界里,效率就是生命。每一个程序员都希望自己的代码既健壮又高效。以下是一些实战技巧,它们可以帮助你提升Java代码的性能,让程序运行得更快、更稳定。
1. 使用局部变量而非静态变量
静态变量在类加载时初始化,如果频繁访问,可能会导致性能问题。局部变量则仅在方法调用时创建和销毁。
// Bad
public static int count = 0;
// Good
public void incrementCount() {
int count = 0; // 局部变量
count++;
}
2. 避免使用过多的反射
反射在运行时解析类、方法、属性,开销较大。尽可能使用配置文件或注解来替代反射。
// Bad
Method method = MyClass.class.getMethod("myMethod");
// Good
public static final String METHOD_NAME = "myMethod";
Method method = MyClass.class.getMethod(METHOD_NAME);
3. 使用基本数据类型而非包装类
包装类(如Integer、Double等)有额外的内存开销,因为它们是对象。在不需要对象特性时,使用基本数据类型。
// Bad
Integer i = new Integer(10);
// Good
int i = 10;
4. 使用并行流提高性能
Java 8引入了Stream API,它支持并行操作,可以显著提高处理大数据集的性能。
// Bad
List<String> result = new ArrayList<>();
for (String s : list) {
result.add(s.toUpperCase());
}
// Good
List<String> result = list.parallelStream().map(String::toUpperCase).collect(Collectors.toList());
5. 优化循环
循环是性能瓶颈之一。尽可能减少循环中的计算量,并使用增强型for循环。
// Bad
for (int i = 0; i < list.size(); i++) {
process(list.get(i));
}
// Good
for (String s : list) {
process(s);
}
6. 使用StringBuffer而非String
当需要频繁修改字符串时,使用StringBuffer可以避免创建多个临时字符串。
// Bad
String s = new String();
s += "Hello";
s += "World";
// Good
StringBuffer sb = new StringBuffer();
sb.append("Hello");
sb.append("World");
String s = sb.toString();
7. 利用缓存
对于频繁访问且计算成本高的操作,使用缓存可以显著提高性能。
public class Cache {
private Map<String, String> cache = new HashMap<>();
public String get(String key) {
return cache.get(key);
}
public void put(String key, String value) {
cache.put(key, value);
}
}
8. 优化数据库查询
使用预编译的SQL语句和合适的索引可以减少数据库查询时间。
// Bad
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE name = ?");
stmt.setString(1, userName);
ResultSet rs = stmt.executeQuery();
// Good
PreparedStatement stmt = connection.prepareStatement("SELECT id, name FROM users WHERE name = ?");
stmt.setString(1, userName);
ResultSet rs = stmt.executeQuery();
9. 使用线程池
避免频繁创建和销毁线程,使用线程池可以提高性能。
ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(() -> {
// 执行任务
});
executor.shutdown();
10. 减少对象创建
对象创建是昂贵的操作。尽量重用对象,减少内存分配。
// Bad
List<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add(new String("Item " + i));
}
// Good
List<String> list = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
11. 使用StringBuilder
StringBuilder是StringBuffer的一个非线程安全的版本,它在单线程环境下有更好的性能。
// Bad
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 1000; i++) {
sb.append("Item ");
}
// Good
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append("Item ");
}
12. 优化算法
选择合适的算法和数据结构可以显著提高性能。
// Bad
for (int i = 0; i < n * n; i++) {
// 计算过程
}
// Good
int[] arr = new int[n];
Arrays.fill(arr, 1);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// 计算过程
}
}
13. 使用枚举而非字符串
枚举类型在运行时占用更少的内存,并且可以在编译时进行类型检查。
// Bad
public void process(String type) {
// 处理类型
}
// Good
public void process(ProcessType type) {
// 处理类型
}
public enum ProcessType {
TYPE1, TYPE2, TYPE3
}
14. 优化I/O操作
减少磁盘I/O操作可以提高性能。
// Bad
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
String line;
while ((line = reader.readLine()) != null) {
// 处理行
}
reader.close();
// Good
FileInputStream fis = new FileInputStream("file.txt");
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
// 处理数据
}
fis.close();
15. 使用finally块
确保资源被释放,即使在发生异常时。
// Bad
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
String line;
while ((line = reader.readLine()) != null) {
// 处理行
}
// 关闭文件
// Good
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("file.txt"));
String line;
while ((line = reader.readLine()) != null) {
// 处理行
}
} finally {
if (reader != null) {
reader.close();
}
}
16. 使用HashMap而非ArrayList
当查找操作比插入操作更频繁时,使用HashMap可以提高性能。
// Bad
List<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
// Good
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < 1000; i++) {
map.put(i, "Item " + i);
}
17. 使用ArrayList而非LinkedList
当顺序访问比随机访问更频繁时,使用ArrayList可以提高性能。
// Bad
LinkedList<String> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
// Good
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
18. 使用BigDecimal而非Double
当需要进行精确的数值计算时,使用BigDecimal可以提高精度。
// Bad
double d = 0.1 + 0.2;
// Good
BigDecimal bd = new BigDecimal("0.1").add(new BigDecimal("0.2"));
19. 使用ArrayList而非Vector
ArrayList在多线程环境下不是线程安全的,但在单线程环境下性能优于Vector。
// Bad
Vector<String> vector = new Vector<>();
for (int i = 0; i < 1000; i++) {
vector.add("Item " + i);
}
// Good
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
20. 使用HashMap而非Hashtable
HashMap是Hashtable的线程不安全版本,性能更好。
// Bad
Hashtable<String, String> table = new Hashtable<>();
table.put("key", "value");
// Good
HashMap<String, String> map = new HashMap<>();
map.put("key", "value");
21. 使用HashSet而非TreeSet
当不需要排序时,使用HashSet可以提高性能。
// Bad
TreeSet<String> set = new TreeSet<>();
for (String s : list) {
set.add(s);
}
// Good
HashSet<String> set = new HashSet<>(list);
22. 使用StringBuilder而非String
当需要频繁修改字符串时,使用StringBuilder可以提高性能。
// Bad
String s = new String();
s += "Hello";
s += "World";
// Good
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append("World");
String s = sb.toString();
23. 使用ArrayList而非LinkedList
当顺序访问比随机访问更频繁时,使用ArrayList可以提高性能。
// Bad
LinkedList<String> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
// Good
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
24. 使用BigDecimal而非Double
当需要进行精确的数值计算时,使用BigDecimal可以提高精度。
// Bad
double d = 0.1 + 0.2;
// Good
BigDecimal bd = new BigDecimal("0.1").add(new BigDecimal("0.2"));
25. 使用HashMap而非Hashtable
HashMap是Hashtable的线程不安全版本,性能更好。
// Bad
Hashtable<String, String> table = new Hashtable<>();
table.put("key", "value");
// Good
HashMap<String, String> map = new HashMap<>();
map.put("key", "value");
26. 使用HashSet而非TreeSet
当不需要排序时,使用HashSet可以提高性能。
// Bad
TreeSet<String> set = new TreeSet<>();
for (String s : list) {
set.add(s);
}
// Good
HashSet<String> set = new HashSet<>(list);
27. 使用StringBuilder而非String
当需要频繁修改字符串时,使用StringBuilder可以提高性能。
// Bad
String s = new String();
s += "Hello";
s += "World";
// Good
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append("World");
String s = sb.toString();
28. 使用ArrayList而非LinkedList
当顺序访问比随机访问更频繁时,使用ArrayList可以提高性能。
// Bad
LinkedList<String> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
// Good
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
29. 使用BigDecimal而非Double
当需要进行精确的数值计算时,使用BigDecimal可以提高精度。
// Bad
double d = 0.1 + 0.2;
// Good
BigDecimal bd = new BigDecimal("0.1").add(new BigDecimal("0.2"));
30. 使用HashMap而非Hashtable
HashMap是Hashtable的线程不安全版本,性能更好。
// Bad
Hashtable<String, String> table = new Hashtable<>();
table.put("key", "value");
// Good
HashMap<String, String> map = new HashMap<>();
map.put("key", "value");
31. 使用HashSet而非TreeSet
当不需要排序时,使用HashSet可以提高性能。
// Bad
TreeSet<String> set = new TreeSet<>();
for (String s : list) {
set.add(s);
}
// Good
HashSet<String> set = new HashSet<>(list);
32. 使用StringBuilder而非String
当需要频繁修改字符串时,使用StringBuilder可以提高性能。
// Bad
String s = new String();
s += "Hello";
s += "World";
// Good
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append("World");
String s = sb.toString();
33. 使用ArrayList而非LinkedList
当顺序访问比随机访问更频繁时,使用ArrayList可以提高性能。
// Bad
LinkedList<String> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
// Good
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
34. 使用BigDecimal而非Double
当需要进行精确的数值计算时,使用BigDecimal可以提高精度。
// Bad
double d = 0.1 + 0.2;
// Good
BigDecimal bd = new BigDecimal("0.1").add(new BigDecimal("0.2"));
35. 使用HashMap而非Hashtable
HashMap是Hashtable的线程不安全版本,性能更好。
// Bad
Hashtable<String, String> table = new Hashtable<>();
table.put("key", "value");
// Good
HashMap<String, String> map = new HashMap<>();
map.put("key", "value");
36. 使用HashSet而非TreeSet
当不需要排序时,使用HashSet可以提高性能。
// Bad
TreeSet<String> set = new TreeSet<>();
for (String s : list) {
set.add(s);
}
// Good
HashSet<String> set = new HashSet<>(list);
37. 使用StringBuilder而非String
当需要频繁修改字符串时,使用StringBuilder可以提高性能。
// Bad
String s = new String();
s += "Hello";
s += "World";
// Good
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append("World");
String s = sb.toString();
38. 使用ArrayList而非LinkedList
当顺序访问比随机访问更频繁时,使用ArrayList可以提高性能。
// Bad
LinkedList<String> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
// Good
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
39. 使用BigDecimal而非Double
当需要进行精确的数值计算时,使用BigDecimal可以提高精度。
// Bad
double d = 0.1 + 0.2;
// Good
BigDecimal bd = new BigDecimal("0.1").add(new BigDecimal("0.2"));
40. 使用HashMap而非Hashtable
HashMap是Hashtable的线程不安全版本,性能更好。
// Bad
Hashtable<String, String> table = new Hashtable<>();
table.put("key", "value");
// Good
HashMap<String, String> map = new HashMap<>();
map.put("key", "value");
41. 使用HashSet而非TreeSet
当不需要排序时,使用HashSet可以提高性能。
// Bad
TreeSet<String> set = new TreeSet<>();
for (String s : list) {
set.add(s);
}
// Good
HashSet<String> set = new HashSet<>(list);
42. 使用StringBuilder而非String
当需要频繁修改字符串时,使用StringBuilder可以提高性能。
// Bad
String s = new String();
s += "Hello";
s += "World";
// Good
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append("World");
String s = sb.toString();
43. 使用ArrayList而非LinkedList
当顺序访问比随机访问更频繁时,使用ArrayList可以提高性能。
// Bad
LinkedList<String> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
// Good
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
44. 使用BigDecimal而非Double
当需要进行精确的数值计算时,使用BigDecimal可以提高精度。
// Bad
double d = 0.1 + 0.2;
// Good
BigDecimal bd = new BigDecimal("0.1").add(new BigDecimal("0.2"));
45. 使用HashMap而非Hashtable
HashMap是Hashtable的线程不安全版本,性能更好。
// Bad
Hashtable<String, String> table = new Hashtable<>();
table.put("key", "value");
// Good
HashMap<String, String> map = new HashMap<>();
map.put("key", "value");
46. 使用HashSet而非TreeSet
当不需要排序时,使用HashSet可以提高性能。
// Bad
TreeSet<String> set = new TreeSet<>();
for (String s : list) {
set.add(s);
}
// Good
HashSet<String> set = new HashSet<>(list);
47. 使用StringBuilder而非String
当需要频繁修改字符串时,使用StringBuilder可以提高性能。
// Bad
String s = new String();
s += "Hello";
s += "World";
// Good
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append("World");
String s = sb.toString();
48. 使用ArrayList而非LinkedList
当顺序访问比随机访问更频繁时,使用ArrayList可以提高性能。
// Bad
LinkedList<String> list = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
// Good
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add("Item " + i);
}
49. 使用BigDecimal而非Double
当需要进行精确的数值计算时,使用BigDecimal可以提高精度。
// Bad
double d = 0.1 + 0.2;
// Good
BigDecimal bd = new BigDecimal("0.1").add(new BigDecimal("0.2"));
50. 使用HashMap而非Hashtable
HashMap是Hashtable的线程不安全版本,性能更好。
// Bad
Hashtable<String, String> table = new Hashtable<>();
table.put("key", "value");
// Good
HashMap<String, String> map = new HashMap<>();
map.put("key", "value");
以上50个实战技巧可以帮助你在Java编程中实现更高的效率。记住,
