MST

星途 面试题库

面试题:Java流式API与集合框架整合时的性能优化策略

在处理大规模集合数据时,使用Java流式API与集合框架整合可能会遇到性能问题。请阐述至少三种性能优化策略,并且说明在什么场景下这些策略会起作用,同时给出简单的代码示例说明优化前后的区别。
34.7万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 减少中间操作创建对象
    • 场景:当中间操作会频繁创建临时对象,且这些对象占用大量内存或创建开销较大时,此策略有效。例如,在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());
    }
}
  1. 并行流与顺序流合理选择
    • 场景:如果集合数据量非常大,且处理操作是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));
    }
}
  1. 避免不必要的装箱拆箱
    • 场景:当处理基本数据类型集合时,若使用了包装类型的流操作,会发生装箱拆箱,影响性能。
    • 优化前(使用包装类型流)代码
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相关操作,避免了装箱拆箱。