合并两个对象的列表以在公共属性的基础上创建第三个对象

时间:2017-10-02 17:30:41

标签: java arraylist merge java-stream

我有两个不同的csv文件,包含两个不同实体的数据,我必须合并两个不同的csv文件,在sql join类型equijoin和left join的基础上创建一个。

所以我创建了第一个实体作为具有属性的类名Customer:

sh yourscript

这个类的对象列表如:

int CustomerId ;
String CustomerName;
int OrderId;

同样,我创建了具有属性的第二个实体Order的类:

Customer c1 = new Customer(CustomerId, CustomerName, OrderId);
1 million objects..

List<Customer> cust = new ArrayList<>();
cust.add(c1);
cust.add(c2);
so on to make list of 1 million object.

现在我需要在orderId的基础上合并这个对象,并生成第三个具有结果类的对象,该结果类具有上述两个类的所有属性。

请建议我使用java stream 8解决方案,以映射列表流以在第三个新结果类中创建内连接和左连接类型示例。

1 个答案:

答案 0 :(得分:0)

除了getter,你的Customer类应该有以下方法:

public boolean orderMatch(Order order) {
    //fixed the attribute name so it would be in camelCase
    return orderId == order.getId();
}

当然,这意味着Order有一个getId() getter方法来获取其id属性。

最后,您需要一个CustomerExtended课程。

class CustomerExtended {
    int customerId ;
    String customerName;
    Order customerOrder;

    public CustomerExtended(Customer customer, Order order) {
        customerId = customer.getId();
        customerName = customer.getName();
        customerOrder = order;
    }
}

现在,您可以创建一个Function来搜索相应的Order并将其附加到Customer

Function<Customer,CustomerExtended> extendCustomer = (c) ->{
    //I used the more descriptive name orderList instead of o1.
    Optional<Order> order = orderList.stream()
                                     .filter(c::orderMatch)
                                     .findFirst();
    if(order.isPresent()) {
        return new CustomerExtended(c,order.get());
    }
    return null;
};

然后您可以通过地图将其应用于Customer列表。

List<CustomerExtended> newCustomerList = customerList.stream()
                                                     .map(c -> extendCustomer.apply(c))
                                                     .collect(Collectors.toList());

编辑:最后一些注释

  • 在将对象添加到列表或填充列表时,应检查ID号是否重复。
  • 出于语义目的,应将Customer对象重命名为CustomerOrder,或者将其分隔为仅用于客户信息的对象和用于存储客户与订单之间关系的对象。
  • 应该更好地处理未找到订单的情况并抛出异常。