【问题标题】:Java8 stream: Iterate over nested listJava8流:迭代嵌套列表
【发布时间】:2020-07-04 20:47:54
【问题描述】:

尝试通过一个简单的示例了解 Java 8 流语法。查看了有关此主题的其他类似问题,但找不到任何与我的示例匹配且对我有用的解决方案。

我有一门课

import java.util.List;

public class Car {
    private String model;
    private String make;
    private String carName;
    private List<Specification> specification;


    public Car(String model, String make, String carName, List<Specification> specification) {
        this.model = model;
        this.make = make;
        this.carName = carName;
        this.specification = specification;
    }

    public String getModel() {
        return model;
    }

    public String getMake() {
        return make;
    }

    public String getCarName() {
        return carName;
    }

    public List<Specification> getSpecification() {
        return specification;
    }
}


public class Specification {
    private String name;
    private String value;

    public String getName() {
        return name;
    }

    public String getValue() {
        return value;
    }

    public Specification(String name, String value) {
        this.name = name;
        this.value = value;
    }
}

我有主要方法

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class RegisterCar {

    public static void main(String[] args) throws IOException {

        List<String> carNames = new ArrayList<>();
        carNames.add("Audi");
        carNames.add("BMW");
        carNames.add("Toyota");
       
        List<String> colour = new ArrayList<>();
        colour.add("red");
        colour.add("white");
    }
}

我想创建一个包含每项汽车名称的汽车对象列表。但是如果汽车名称是“Audi”或“BMW”,它应该只创建一个类的对象,如下所示

        List<Car> carList = new ArrayList<>();
        
        Specification musicSystem = new Specification("MusicSysten" , "present");
        
        List<Specification> specList= new ArrayList<>();
        specList.add(musicSystem);
        
        carList.add(new Car("Q5", "2020", "Audi", specList));
        carList.add(new Car("X2", "2020", "BMW", specList));


但如果项目是“Toyota”,那么它应该为每种颜色创建两个对象。

 List<Specification> specListRed= new ArrayList<>();
        specListRed.add(musicSystem);
        specListRed.add(redColor);

        List<Specification> specListWhite= new ArrayList<>();
        specListWhite.add(musicSystem);
        specListWhite.add(whiteColor);

        carList.add(new Car("Camry", "2020", "Toyota", specListRed));
        carList.add(new Car("Camry", "2020", "Toyota", specListWhite));

我正在尝试编写一种通用方法来创建对象并添加到列表中。我已经尝试过这样的事情,但我不会为 Toyota 创建正确的两个对象。

carList =  carNames.stream()
                .map(carName -> new Car(model, make, carName, specList))
                .collect(Collectors.toList());

请建议我如何通过流实现这一点。

【问题讨论】:

标签: java list java-8 nested java-stream


【解决方案1】:

如果您希望名称“Toyota”被使用两次,它应该包含在名称列表中两次,因为 map() 中的 lambda 对每个名称都执行。

但在您的地图调用中:您从哪里获取、建模和制作?

【讨论】:

  • 我会将品牌和型号作为列表的参数发送。由于颜色列表不固定,我无法在列表中添加两次 Toyota。
  • .forEach 可能比.map 更合适。
  • 这没有真正意义@EmrahDiril ..他正在将它们聚合在一个集合中
  • 我认为列表和规范的组合在一般地图调用中不起作用
【解决方案2】:

您需要了解的第一件事是map 操作始终保留与您的输入相同的数量(即基数)。 如果您将传递 3 个项目 - 无论您拥有哪个功能,结果都将始终为 3。

接下来值得研究的事情:flatMap 函数。此函数可以将任意数量的输入转换为任意数量的结果!这看起来是我们需要的。

   var carList = carNames.stream()
                .flatMap(carName -> {
                    if (carName.equals("Toyota") {
                      return Stream.of(new Car(model, make, carName, specList1),
                                       new Car(model, make, carName, specList2)); 
                    } else {
                      return Stream.of(new Car(model, make, carName, specList));
                    })
                .collect(Collectors.toList());

【讨论】:

  • 感谢您的解释。我们可以优化这个if (carName.equals("Toyota") { return Stream.of(new Car(model, make, carName, specList1), new Car(model, make, carName, specList2)); } 我想知道我是否可以在颜色列表中使用流
  • @codemaster001 - 你可以写成carName -&gt; carName.equals("Toyota") ? Stream.of(new Car(model, make, carName, specList1), new Car(model, make, carName, specList2)) : Stream.of(new Car(model, make, carName, specList))
【解决方案3】:

因为这完全是关于创建和持有对象。关注 equals() 和 hashcode() 方法。

@Override
public boolean equals(Object o) {

    if (o == this) return true;
    if (!(o instanceof Car)) {
        return false;
    }
    Car car = (Car) o;
    if (carName.equals("BMW")) {
        return true;
    }
    if (carName.equals("Toyota")) {
        return false;
    }
    return Objects.equals(carName , car.carName);
}

@Override
public int hashCode() {
    return 1;
}

司机素质

    List<String> carNames = new ArrayList<>();
    carNames.add("Audi");
    carNames.add("BMW");
    carNames.add("Toyota");
    carNames.add("Toyota");
    List<String> colours = new ArrayList<>();
    colours.add("red");
    colours.add("white");

  

     Set carList = carNames.stream()
            .map(carName -> {
                Set ss = new HashSet();
                if (carName.equals("Toyota")) {
                    ss.addAll(colours.stream().map(colr -> new Car("model" , "make" , carName , null)).collect(Collectors.toSet()));
                } else {
                    ss.add(new Car("model" , "make" , carName , null));
                }
                return ss;
            })
            .collect(HashSet::new, Set::addAll, Set::addAll);

【讨论】:

    猜你喜欢
    • 2015-05-26
    • 2018-03-08
    • 2011-10-14
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    相关资源
    最近更新 更多