3 votes

Jointure gauche pour 2 listes d'objets en Java

J'ai 2 listes d'objets en Java

List<Object1> list1
List<Object2> list2

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

Object2 has fields:
- fieldB
- fieldE
- fieldF

Ainsi, l'objet 1 et l'objet 2 ont le même champ "fieldB".

Ce que je voulais faire, c'est implémenter une sorte de "LEFT JOIN", qui joindrait tous les objets de liste1 y liste2 et crée un autre Liste list3Objet3 contient tous les champs des deux Objet1 y Objet2

Je dispose d'un grand nombre de données, l'approche doit donc être très rapide. Et des recommandations sur la façon de l'implémenter en Java ?

1voto

tsolakp Points 4658

Vous pouvez essayer d'utiliser l'opération parallèle de Java stream afin d'accélérer les choses :

    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 contiendra votre résultat.

0voto

daniu Points 8648

Vous pouvez le faire en une seule itération par liste en créant un fichier Map en un point :

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

qui créera une carte avec les valeurs du champ B comme clés et tous les objets de list1 avec la valeur correspondante du champ B comme valeurs.

Vous pouvez maintenant diffuser l'autre liste et la fusionner avec la liste appropriée. Object1 des listes correspondantes.

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

avec une méthode d'aide

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X