如何通过Java Stream按carId分组将List<Car>转换为Set<CarCombined>
使用Java Stream将List转换为Set
需求说明
现有一个包含Car对象的List<Car>,Car类核心定义如下:
class Car { private int carId; private long carSN; public Car(int carId, long carSN) { this.carId = carId; this.carSN = carSN; } public int getCarId() { return carId; } public long getCarSN() { return carSN; } }
列表中的具体数据:
1, 123 2, 456 3, 123 1, 789
需要将其转换为Set<CarCombined>,CarCombined类核心定义如下:
class CarCombined { private int carId; private Set<Long> carSNs; public CarCombined(int carId, Set<Long> carSNs) { this.carId = carId; this.carSNs = carSNs; } public int getCarId() { return carId; } public Set<Long> getCarSNs() { return carSNs; } // 必须重写equals和hashCode,确保Set基于carId去重 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CarCombined that = (CarCombined) o; return carId == that.carId; } @Override public int hashCode() { return Objects.hash(carId); } @Override public String toString() { return carId + ", " + carSNs; } }
期望转换后的Set<CarCombined>数据:
1, [123, 789] 2, [456] 3, [123]
解决方案(Java Stream实现)
可以通过Stream的分组+映射操作完成转换,代码如下:
import java.util.*; import java.util.stream.Collectors; public class CarConversionDemo { public static void main(String[] args) { List<Car> carList = Arrays.asList( new Car(1, 123), new Car(2, 456), new Car(3, 123), new Car(1, 789) ); Set<CarCombined> carCombinedSet = carList.stream() // 按carId分组,将对应carSN收集为Set .collect(Collectors.groupingBy( Car::getCarId, Collectors.mapping(Car::getCarSN, Collectors.toSet()) )) // 将分组结果映射为CarCombined对象 .entrySet().stream() .map(entry -> new CarCombined(entry.getKey(), entry.getValue())) // 收集到Set中 .collect(Collectors.toSet()); // 验证输出 carCombinedSet.forEach(System.out::println); } }
关键细节说明
- 分组逻辑:使用
Collectors.groupingBy按carId分组,同时通过Collectors.mapping提取carSN并收集为Set,自动实现同carId下SN的去重。 - Set去重保证:
CarCombined必须基于carId重写equals和hashCode,否则Set无法识别重复的carId对象,会出现重复项。 - 顺序控制:如果需要保留SN的插入顺序,可以将
Collectors.toSet()替换为Collectors.toCollection(LinkedHashSet::new)。
内容的提问来源于stack exchange,提问作者Omar Attareefy
相关产品推荐
相关产品推荐

