1. 使用StringBuilder拼接字符串
如果你在循环中拼接字符串,最好使用StringBuilder。使用+操作符时,Java每次都会创建一个新的字符串,这可能会降低效率,请不要写成如下样态。
String result = "";
for (String s : words) {
result += s;
}
不妨尝试使用StringBuilder。
StringBuilder result = new StringBuilder();
for (String s : words) {
result.append(s);
}
String finalResult = result.toString();
2. 尽可能重用对象
每次创建新对象都会消耗大量内存和时间。我们应尽可能重用对象。需要注意的是,我们也应该明智地使用它们,比如只在对象状态频繁变化或生命周期需要多次使用时才这样做。示例如下。
// 一次性创建对象
MyClass obj = new MyClass();
for (int i = 0; i < 1000; i++) {
obj.doSomething();
}
3. 使用原始类型而不是包装类
我们需要意识到Integer、Double和Boolean比原始数据类型如int、double和boolean慢。因此,我们需要避免冗余地使用它们。所以,优先选择:
int number = 5;
而不是:
Integer number = new Integer(5);
4. 选择合适的数据结构
当你需要快速操作时,选择HashMap或HashSet而不是List。示例如下。
Set names = new HashSet<>();
names.add("Alice");
names.add("Bob");
if (names.contains("Alice")) {
// 执行操作
}
5. 避免不必要的类型转换
类型转换可能会降低效率。如果你知道你正在处理的对象类型,尽量避免转换它们。不要这样做。
Object obj = "Hello";
String str = (String) obj;
而是直接:
String str = "Hello";
6. 缓存常用值
缓存可能是双刃剑,所以我们需要明智地使用它。我们不应该过度缓存,也不应该完全避免它。但是,当需要进行繁重的计算或频繁访问通常不会改变的数据时,我们应该使用缓存。示例缓存可能是双刃剑,所以我们需要明智地使用它。我们不应该过度缓存,也不应该完全避免它。但是,当需要进行繁重的计算或频繁访问通常不会改变的数据时,我们应该使用缓存。示例如下。
Map cache = new HashMap<>();
int getFactorial(int n) {
if (cache.containsKey(n)) {
return cache.get(n);
} else {
int result = calculateFactorial(n);
cache.put(n, result);
return result;
}
}
7. 限制同步的使用
在多线程程序中,同步可能会导致延迟。只在必要时使用,并保持同步块简短。示例如下。
synchronized (this) {
// 只有需要同步的关键部分
sharedResource.update();
}
8. 小心循环中的异常
抛出和捕获异常比常规代码执行慢。尽量避免在循环中使用它们。不要这样做。
for (int i = 0; i < data.length; i++) {
try {
process(data[i]);
} catch (Exception e) {
// 处理异常
}
}
而是在处理之前验证:
for (int i = 0; i < data.length; i++) {
if (isValid(data[i])) {
process(data[i]);
}
}
但如果问题出在数据本身,你应该在处理之前过滤或验证数据。
Stream.of(data)
.filter(this::isValid)
.forEach(this::process);
所以,根据你的具体情况选择最佳方法。
9. 使用高效的循环
编写循环的方式可能会有所不同。例如,遍历列表时,如果可能,使用带索引的循环。示例如下。
for (int i = 0; i < list.size(); i++) {
doSomething(list.get(i));
}
10. 为工作选择最易读的循环
使用Java Streams可以使你的代码更清晰、更容易理解。使用for-each的例子如下。
for (String item : list) {
doSomething(item);
}
使用Streams的例子如下。
list.stream().forEach(item -> doSomething(item));