简体   繁体   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

I have a list of Beans ( List 1 ) and I want to convert it to another list ( List 2 ).我有一个 Bean 列表( List 1 ),我想将其转换为另一个列表( List 2 )。

I've managed to achieve that.我已经成功地做到了这一点。 But I have the impression it made it too complicated : pick out the id 's + loop + stream again.但我觉得它太复杂了:再次挑出id的 +循环+

My question is : is it possible to make it simpler ?我的问题是:是否有可能使它更简单?

Sample data - List1:样本数据 - 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]]

Sample data - List2:样本数据 - 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]]]

My code:我的代码:

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;
    }
}

Your current solution performs an iteration over the list of customers for every unique id .您当前的解决方案对每个唯一id客户列表执行迭代。

As @Johannes Kuhn has pointed out in the comments, you can eliminate redundant iterations by making use of the collector groupingBy(classifier, downstream) .正如@Johannes Kuhn在评论中指出的那样,您可以通过使用收集器groupingBy(classifier, downstream)来消除冗余迭代。 With this collector , we can map each customer with unique id to a list of cars in a single iteration.使用这个收集器,我们可以在一次迭代中将每个具有唯一id客户映射到汽车列表

And then construct a list of ImprovedCustomer objects based on every entry of the map generated by groupingBy() .然后根据groupingBy()生成的地图的每个条目构造一个ImprovedCustomer对象列表。

Note: that in order to use this approach, either Customer class should implement equals/hashCode contract based on the id and name properties, or we need to use an auxiliary record (or class) that would wrap a Customer object.注意:为了使用这种方法,要么Customer类应该基于idname属性实现equals/hashCode契约,要么我们需要使用一个辅助记录(或类)来包装一个Customer对象。 For simplicity, I'll assume that we can rely on the Customer class equals/hashCode implementations.为简单起见,我假设我们可以依赖Customer类的equals/hashCode实现。

So, in the code below as classifier function I've applied Function.identity() (ie a key would be a customer itself) and as downstream collector a combination of collectors mapping() and toList() , which transforms every customer into a Car object, and collect the cars mapped to the same customer into a list.因此,在下面的代码中作为分类器函数,我应用了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.

相关问题 使用Java Streams按属性将对象列表组合在一起,并将它们减少为具有另一个属性平均值的新对象列表 - Using Java Streams to group together a List of objects by an attribute and reduce them to a new list of object with the average of another attribute Java 流设置 object 列表的每个属性与另一个列表 - Java streams set each attribute of object List with another List 使用流将自定义对象列表合并到单个列表 Object Java 8 - Merge List of Custom Objects to a Single List Object using Streams Java 8 Java 8 Streams - 使用流将相同类型的多个对象映射到列表 - Java 8 Streams - Map Multiple Object of same type to a list using streams 使用Streams将列表对象复制到具有修改内容的另一个列表对象 - copying list object to another list object with modified content using Streams 如何使用流将对象列表转换为另一个列表对象? - How to convert list of object to another list object using streams? 使用 Streams,查看列表是否包含来自另一个列表的 object 的属性 - Using Streams, see if a list contains a property of an object from another list 使用Java流将列表转换为映射 - Transform list to mapping using java streams 将列表列表转换为另一个对象的列表 - Transform a List of List into into a List of another object 使用 Java 8 Streams 从另一个创建对象列表 - Create list of object from another using Java 8 Streams
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM