面试题答案
一键面试- 减少中间操作创建对象
- 场景:当中间操作会频繁创建临时对象,且这些对象占用大量内存或创建开销较大时,此策略有效。例如,在
map
操作中,若转换操作创建的新对象较为复杂。 - 优化前代码:
- 场景:当中间操作会频繁创建临时对象,且这些对象占用大量内存或创建开销较大时,此策略有效。例如,在
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StreamPerformance {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
numbers.add(i);
}
List<String> result = numbers.stream()
.map(n -> new StringBuilder().append(n).append("_suffix").toString())
.collect(Collectors.toList());
}
}
- 优化后代码:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StreamPerformance {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
numbers.add(i);
}
StringBuilder sb = new StringBuilder();
List<String> result = numbers.stream()
.map(n -> {
sb.setLength(0);
return sb.append(n).append("_suffix").toString();
})
.collect(Collectors.toList());
}
}
- 并行流与顺序流合理选择
- 场景:如果集合数据量非常大,且处理操作是CPU密集型(例如复杂的计算),使用并行流可能提升性能。但如果操作涉及共享资源的修改等,并行流可能导致数据不一致问题,此时应使用顺序流。
- 优化前(顺序流)代码:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StreamPerformance {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
numbers.add(i);
}
long start = System.currentTimeMillis();
List<Integer> result = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList());
long end = System.currentTimeMillis();
System.out.println("顺序流时间: " + (end - start));
}
}
- 优化后(并行流)代码:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StreamPerformance {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
numbers.add(i);
}
long start = System.currentTimeMillis();
List<Integer> result = numbers.parallelStream()
.map(n -> n * n)
.collect(Collectors.toList());
long end = System.currentTimeMillis();
System.out.println("并行流时间: " + (end - start));
}
}
- 避免不必要的装箱拆箱
- 场景:当处理基本数据类型集合时,若使用了包装类型的流操作,会发生装箱拆箱,影响性能。
- 优化前(使用包装类型流)代码:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StreamPerformance {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
numbers.add(i);
}
long start = System.currentTimeMillis();
int sum = numbers.stream()
.mapToInt(Integer::intValue)
.sum();
long end = System.currentTimeMillis();
System.out.println("使用包装类型流时间: " + (end - start));
}
}
- 优化后(使用基本类型流)代码:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StreamPerformance {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
numbers.add(i);
}
long start = System.currentTimeMillis();
int sum = numbers.stream()
.mapToInt(Integer::intValue)
.sum();
long end = System.currentTimeMillis();
System.out.println("使用基本类型流时间: " + (end - start));
}
}
在这个例子中,优化前使用mapToInt
先将Integer
对象转换为int
,存在装箱拆箱。优化后直接使用IntStream
相关操作,避免了装箱拆箱。