Left Join for Java中的2个对象列表

时间:2018-03-02 15:28:24

标签: java lambda left-join

我有两个Java对象列表

# in the controller (this returns a hash)
@locations = Country.joins(:user).order(:name).group(:name).count

# in your view
- @locations.each do |name, count|
  %li
    = name
    = "(#{count})" if count > 1

因此,Object1和Object2都具有相同的字段“fieldB”。

我想要做的是实现某种“LEFT JOIN”,它将加入 list1 list2 中的所有对象,并创建另一个列表list3 ,其中 Object3 包含 Object1 Object2

的所有字段

我有大量数据,因此方法应该非常快。 关于如何在Java中实现它的建议?

2 个答案:

答案 0 :(得分:1)

您可以尝试使用Java流的并行操作来加快速度:

case Some(order)

List<Object3> list3 = list1.stream().parallel() .map( o1 -> merge( new Object3(), o1 ) ) .collect( Collectors.toList() ); Map<Object, Object3> map = list3.stream().parallel() .collect( Collectors.toConcurrentMap( Object3::getFieldB, Function.identity() ) ); list2.stream().parallel().forEach( o2 -> { Object3 o3 = map.get( o2.getFieldB() ); if (o3 != null) merge(o3, o2); } ); Object3 merge(Object3 o3, Object1 o1){...} Object3 merge(Object3 o3, Object2 o2){...} 将包含您的结果。

答案 1 :(得分:0)

通过在一次运行中创建Map,您可以在每个列表中进行一次迭代:

Map<FieldBType, List<Object1>> map = list1.parallelStream()
                         .groupingBy(Object1::getFieldB);

将创建一个地图,其中FieldB的值为键,list1中的所有对象都具有相应的fieldB值作为值。

现在,您可以流式传输其他列表,并与相应列表中的相应Object1合并。

List<Object3> = list2.parallelStream()
    .flatMap(o2 -> merge(o2, map.getOrDefault(o2.getFieldB(), Collections.emptyList())
    .collect(Collectors.toList());

使用辅助方法

// creates a stream of Object3 from the Object1s from the list
// merged with the values of the given Object2
Stream<Object3> merge(Object2 o2, List<Object1> o1s) {
    return o2s.parallelStream().map(o2 -> merge(o1, o2));
}

Object3 merge(Object o1, Object o2) { ... }