繁体   English   中英

合并与 List 中每个唯一对象相关的数据,并使用 Streams 将它们转换为另一种类型的 List

[英]Merge the data relating to each unique Object in a List and transform them into a List of another Type using Streams

我有一个 Bean 列表( List 1 ),我想将其转换为另一个列表( List 2 )。

我已经成功地做到了这一点。 但我觉得它太复杂了:再次挑出id的 +循环+

我的问题是:是否有可能使它更简单?

样本数据 - List1:

[Customer [id=1, name=jon, carType=fiat, color=black], 
 Customer [id=2, name=din, carType=ford, color=yellow], 
 Customer [id=1, name=jon, carType=benz, color=white], 
 Customer [id=1, name=jon, carType=volvo, color=red], 
 Customer [id=3, name=fin, carType=volvo, color=black], 
 Customer [id=3, name=fin, carType=fiat, color=green], 
 Customer [id=4, name=lara, carType=bmw, color=red], 
 Customer [id=5, name=tina, carType=toyota, color=white], 
 Customer [id=5, name=tina, carType=fiat, color=yelow], 
 Customer [id=6, name=bogi, carType=benz, color=black]]

样本数据 - List2:

ImprovedCustomer [id=1, name=jon, cars=[Car [carType=fiat, color=black], Car [carType=benz, color=white], Car [carType=volvo, color=red]]]
ImprovedCustomer [id=2, name=din, cars=[Car [carType=ford, color=yellow]]]
ImprovedCustomer [id=3, name=fin, cars=[Car [carType=volvo, color=black], Car [carType=fiat, color=green]]]
ImprovedCustomer [id=4, name=lara, cars=[Car [carType=bmw, color=red]]]
ImprovedCustomer [id=5, name=tina, cars=[Car [carType=toyota, color=white], Car [carType=fiat, color=yelow]]]
ImprovedCustomer [id=6, name=bogi, cars=[Car [carType=benz, color=black]]]

我的代码:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class App {

    public static void main(String[] args) {
        List<Customer> list = new ArrayList<>();
        list.add(new Customer(1, "jon", "fiat", "black"));
        list.add(new Customer(2, "din", "ford", "yellow"));
        list.add(new Customer(1, "jon", "benz", "white"));
        list.add(new Customer(1, "jon", "volvo", "red"));
        list.add(new Customer(3, "fin", "volvo", "black"));
        list.add(new Customer(3, "fin", "fiat", "green"));
        list.add(new Customer(4, "lara", "bmw", "red"));
        list.add(new Customer(5, "tina", "toyota", "white"));
        list.add(new Customer(5, "tina", "fiat", "yelow"));
        list.add(new Customer(6, "bogi", "benz", "black"));

        List<Integer> ids = list.stream().map(Customer::getId).distinct().collect(Collectors.toList());

        List<ImprovedCustomer> ImprovedCustomers = new ArrayList<>();

        for (int id : ids) {
            ImprovedCustomer improvedCustomer = new ImprovedCustomer(id);
            List<Car> collect = list.stream().filter(a -> a.getId().equals(id)).map(a -> {
                if (improvedCustomer.getName() == null) {
                    improvedCustomer.setName(a.getName());
                }
                return new Car(a.getCarType(), a.getColor());
            }).collect(Collectors.toList());

            improvedCustomer.setCars(collect);
            ImprovedCustomers.add(improvedCustomer);
        }
    }
}

class Customer {

    private Integer id;
    private String name;
    private String carType;
    private String color;

    public Customer(Integer id, String name, String carType, String color) {
        super();
        this.id = id;
        this.name = name;
        this.carType = carType;
        this.color = color;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCarType() {
        return carType;
    }

    public void setCarType(String carType) {
        this.carType = carType;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

class Car {

    private String carType;
    private String color;

    public Car(String carType, String color) {
        super();
        this.carType = carType;
        this.color = color;
    }

    public String getCarType() {
        return carType;
    }

    public void setCarType(String carType) {
        this.carType = carType;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

class ImprovedCustomer {

    private Integer id;
    private String name;
    private List<Car> cars;

    public ImprovedCustomer() {
        super();
    }

    public ImprovedCustomer(Integer id) {
        super();
        this.id = id;
    }

    public ImprovedCustomer(Integer id, String name, List<Car> cars) {
        super();
        this.id = id;
        this.name = name;
        this.cars = cars;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Car> getCars() {
        return cars;
    }

    public void setCars(List<Car> cars) {
        this.cars = cars;
    }
}

您当前的解决方案对每个唯一id客户列表执行迭代。

正如@Johannes Kuhn在评论中指出的那样,您可以通过使用收集器groupingBy(classifier, downstream)来消除冗余迭代。 使用这个收集器,我们可以在一次迭代中将每个具有唯一id客户映射到汽车列表

然后根据groupingBy()生成的地图的每个条目构造一个ImprovedCustomer对象列表。

注意:为了使用这种方法,要么Customer类应该基于idname属性实现equals/hashCode契约,要么我们需要使用一个辅助记录(或类)来包装一个Customer对象。 为简单起见,我假设我们可以依赖Customer类的equals/hashCode实现。

因此,在下面的代码中作为分类器函数,我应用了Function.identity() (即,一个将是客户本身)和作为下游收集器收集器mapping()toList()的组合,它将每个客户转换为Car对象,并将映射到同一客户的汽车收集到一个列表中。

public static void main(String[] args) {
    List<Customer> customers = // initializing the list of customers

    List<ImprovedCustomer> improvedCustomers = customers.stream()
        .collect(Collectors.groupingBy(
            Function.identity(),
            Collectors.mapping(cust -> new Car(cust.getCarType(), cust.getColor()),
                Collectors.toList())
        ))
        .entrySet().stream()
        .map(entry -> new ImprovedCustomer(entry.getKey().getId(), entry.getKey().getName(), entry.getValue()))
        .collect(Collectors.toList());
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM