如何使用Stream改写嵌套for循环?Java代码优化咨询
Hey there! Let's clean up that nested loop with Java Stream API—it'll make your code more concise and expressive. Let's break down the refactoring step by step.
直接替换嵌套循环的Stream实现(和原逻辑完全一致)
This version keeps the core behavior of modifying the original Student objects, just like your initial code:
students.forEach(student -> { List<Laptop> filteredLaptops = student.getLaptopList() .stream() // Filter laptops where color ends with "RED" (add null check to avoid NPE) .filter(laptop -> laptop.getColour() != null && laptop.getColour().endsWith("RED")) // Explicitly collect to ArrayList to match your original code's collection type .collect(Collectors.toCollection(ArrayList::new)); student.setLaptopList(filteredLaptops); });
Why this is better?
- Eliminates boilerplate code for manually creating
ArrayListand nested loops - Uses
filterto directly express your selection rule, making the logic easier to read at a glance - Retains exactly the same business logic as your original code
More robust version (handles null values)
If student.getLaptopList() could return null, or laptop.getColour() might be null, add null safeguards to avoid NullPointerException:
import java.util.Collections; import java.util.Optional; import java.util.stream.Collectors; students.forEach(student -> { List<Laptop> filteredLaptops = Optional.ofNullable(student.getLaptopList()) // Replace null list with an empty one to safely stream .orElse(Collections.emptyList()) .stream() .filter(laptop -> laptop.getColour() != null && laptop.getColour().endsWith("RED")) .collect(Collectors.toCollection(ArrayList::new)); student.setLaptopList(filteredLaptops); });
Functional style (no side effects, create new objects)
If you prefer functional programming practices or work with immutable Student classes (no setters), use map to create new Student instances with filtered laptop lists:
List<Student> updatedStudents = students.stream() .map(student -> { List<Laptop> filteredLaptops = Optional.ofNullable(student.getLaptopList()) .orElse(Collections.emptyList()) .stream() .filter(laptop -> laptop.getColour() != null && laptop.getColour().endsWith("RED")) .collect(Collectors.toList()); // Assume Student has a constructor that takes all necessary properties, or use a Builder return new Student(student.getId(), student.getName(), filteredLaptops); }) .collect(Collectors.toList());
This approach avoids modifying original objects, which is ideal for immutable data models.
内容的提问来源于stack exchange,提问作者abhinash pandey

