Java8流-集合中具有相同id的对象上的操作

Java8流-集合中具有相同id的对象上的操作,java,collections,java-8,java-stream,Java,Collections,Java 8,Java Stream,我的问题有点复杂(我想),所以我将尝试使用一个例子。希望你能理解我的问题 假设我有一个用户列表: List<User> users; 列出用户; 其中: public class User{ private List<Car> cars; } public class Car{ private String code; private List<Feature> features; } public class Feature{

我的问题有点复杂(我想),所以我将尝试使用一个例子。希望你能理解我的问题

假设我有一个用户列表:

List<User> users;
列出用户;
其中:

public class User{
    private List<Car> cars;
}

public class Car{
    private String code;
    private List<Feature> features;
}

public class Feature{
    private String code;
}
公共类用户{
私家车名单;
}
公车{
私有字符串码;
私有列表功能;
}
公共类功能{
私有字符串码;
}
我想要实现的是从用户列表中获取汽车列表,但我也希望这个列表是不同的(没有具有相同代码的汽车),但我希望单个汽车对象具有来自具有相同代码的不同汽车的所有功能,这就是我失败的地方

现在我有

List<Car> cars = users
        .stream()
        .flatMap(user -> user.getCars())
        .???
List cars=用户
.stream()
.flatMap(用户->用户.getCars())
.???

我知道我可以通过使用谓词的代码来过滤汽车,但我很难为我要离开的汽车添加功能。有没有一个干净的方法来处理流

这一切归结为一个问题,你想如何得到一辆拥有所有关节功能的
汽车。您肯定不想修改某个用户的任意
Car
实例。因此,要支持加入这些
功能
s,您必须在加入功能列表后构建一个新的
汽车
实例

这可以通过以下方式完成:

List<Car> cars =
    users.stream()
    .flatMap(user -> user.getCars().stream())
    .collect(Collectors.groupingBy(Car::getCode,
        Collectors.mapping(Car::getFeatures, Collector.of(
            ArrayList<Feature>::new, List::addAll, (a,b)->{a.addAll(b);return a;}))))
    .entrySet().stream()
    .map(e -> new Car(e.getKey(), e.getValue()))
    .collect(Collectors.toList());

这首先将具有相同
代码的
汽车
功能
收集到
集合
,消除重复但保留顺序(对于相关的情况)并在构造结果
Car
实例时将
转换为
列表

这一切归结为一个问题,即如何获得一辆具有所有关节特征的
汽车。您肯定不想修改某个用户的任意
Car
实例。因此,要支持加入这些
功能
s,您必须在加入功能列表后构建一个新的
汽车
实例

这可以通过以下方式完成:

List<Car> cars =
    users.stream()
    .flatMap(user -> user.getCars().stream())
    .collect(Collectors.groupingBy(Car::getCode,
        Collectors.mapping(Car::getFeatures, Collector.of(
            ArrayList<Feature>::new, List::addAll, (a,b)->{a.addAll(b);return a;}))))
    .entrySet().stream()
    .map(e -> new Car(e.getKey(), e.getValue()))
    .collect(Collectors.toList());

在构建结果
汽车
实例时,首先将
汽车
功能
收集到一个
集合
,消除重复项但保留顺序(对于相关的情况),并将
集合
转换成一个
列表

可能是因为“我希望单个汽车对象具有来自不同汽车的所有功能”是一个非常分散的规范。您如何期望
汽车
对象具有来自其他汽车的功能?您在谈论什么功能?这与现实生活中的汽车有什么关系吗?有一种方法可以使用
distinct()
但这仅在
car.equals(car)时有效
但是需要您让equals方法只对汽车代码起作用。另一种方法是将代码映射到功能,例如,
映射
,它不是汽车列表,而是您需要的信息。或者最后,您编写一个自定义收集器,如果没有,它将检查带有代码的汽车列表“不要添加,那辆车,如果它添加了,就向那辆车添加功能。如果你创建一个
公共汽车合并功能(car car1,car2)
方法,你可以将它变成一个收集器,我不知道这是否有助于解决整个问题,但它可能会让你更接近。也许你失败是因为“我希望单个汽车对象具有来自不同汽车的所有功能”是一个非常分散的规范。您如何期望
汽车
对象具有来自其他汽车的功能?您在谈论什么功能?这与现实生活中的汽车有什么关系吗?有一种方法可以使用
distinct()
但这仅在
car.equals(car)时有效
但是需要您让equals方法只对汽车代码起作用。另一种方法是将代码映射到功能,例如,
映射
,它不是汽车列表,而是您需要的信息。或者最后,您编写一个自定义收集器,如果没有,它将检查带有代码的汽车列表't add,那辆车,如果它添加了,就向那辆车添加功能。如果你创建了一个
公共汽车合并功能(car car1,car2)
method,您可以将其转换为收集器,我不知道这是否有助于解决整个问题,但这可能会让您更进一步。感谢您提供详细的答案。我在使用此解决方案时遇到了一个问题,这可能是因为我对我的意图描述得非常糟糕。理想的解决方案是消除重复的功能,就像您所说的那样已预测。在我的项目中使用此方法时出现一些错误:
类型集未定义此处适用的add(Object,Object)
方法addAll(Object)未定义类型对象
类型Car中的方法setFeatures(Collection)不适用于参数(Object)
感谢您提供详细的回答。我在使用此解决方案时遇到了一个问题,这可能是因为我对我的意图描述得很糟糕。理想的解决方案是消除重复的功能,正如您所预测的那样。在我的项目中使用此方法时出现了一些错误:
类型集没有定义add(Object,Object)适用于此处
类型对象的方法addAll(对象)未定义
类型Car中的方法setFeatures(集合)不适用于参数(对象)