左加入Java中的2个对象列表[重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了左加入Java中的2个对象列表[重复]相关的知识,希望对你有一定的参考价值。

这个问题在这里已有答案:

我在Java中有2个对象列表

List<Object1> list1
List<Object2> list2

Object1 has fields:
- fieldA
- fieldB
- fieldC
- fieldsD

Object2 has fields:
- fieldB
- fieldE
- fieldF

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

我想要做的是实现某种“LEFT JOIN”,它将连接list1和list2中的所有对象并创建另一个List list3,其中Object3包含Object1和Object2中的所有字段

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

答案

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

    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){...}

list3将包含您的结果。

另一答案

通过在一次运行中创建Map,您可以在每个列表的一次迭代中执行此操作:

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

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

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

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) { ... }

以上是关于左加入Java中的2个对象列表[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何创建片段以重复变量编号中的代码行

防止mysql中的重复加入视图

左外侧加入无重复行

在片段中启动 Activity [重复]

22.java方法的定义

13 个非常有用的 Python 代码片段