0
votes

Imbriqué lambda foreach avec deux listes différentes (l'une des listes doit être définitive?)

Pourriez-vous m'aider à écrire deux boucles foreach imbriquées pour deux listes différentes où j'ai besoin de comparer l'attribut d'objet spécifique stocké dans les deux listes?

List<Object1> listOfObject1 = mapper.selectObject1ByName(value1);
List<Object2> listOfObject2 = mapper.selectObject2ByName(value2);

listOfObject1.stream().forEach(object1 -> {
            listOfObject2.stream().forEach(object2 -> {
                if (object1.getCode() == object2.getCode()) {
                    //do something
                }
            });
        });

Bien sûr, j'ai eu cette erreur: "La variable utilisée dans l'expression lambda doit être finale ou effectivement finale" mais je ne peux pas rendre la liste définitive, car il y a une logique de décision ci-dessus où je remplis les listes avec les valeurs correctes et je J'écris à la liste sur plus d'endroits.


4 commentaires

Vous pouvez copier votre liste dans une liste finale si votre «faire quelque chose» ne réaffecte pas la liste


Pourquoi ne pas simplement utiliser (amélioré) pour les boucles?


Sinon, vous pouvez utiliser de simples boucles for old


J'étais curieux de savoir s'il existe un autre moyen que de faire une autre copie de la liste ou d'utiliser «l'ancienne» boucle foreach. Quelque chose de gentil avec les lambdas.


3 Réponses :


0
votes

Je pense que vous pouvez définir une fonction de comparaison et l'utiliser pour comparer les données de vos listes. Je suggère d'utiliser Comparator classe java Comparator . De cette façon, l'utilisateur doit définir les fonctions compare(T o1, T o2) et equals(Object obj) .


0 commentaires

0
votes

Nous pouvons simplement utiliser hashMap pour conserver tous les éléments de list2.Ensuite, nous pouvons itérer les éléments de list1 et vérifier s'il existe ou non dans hashMap.

list1
.stream()
.filter(e->mapOfElements.get(e.getCode())
.collect(Collectors.toList());

Ensuite, vous pouvez effectuer l'opération requise.

list2.forEach (e-> mapOfElements.put (e.getCode (), e));

final Map<String,Object> mapOfElements= new HashMap<>();


0 commentaires

1
votes

Si la mise en œuvre de // do something partie nécessite soit de object1 ou object2 , puis les codes appropriés pourraient être recueillis dans un ensemble distinct, qui est ensuite utilisé pour filtrer les entrées dans l'autre liste.

Par exemple, si object2 doit être consommé:

Map<Integer, List<Object1>> mapCodes = listOfObject1
        .stream()
        .collect(Collectors.groupingBy(Object1::getCode));

listOfObject2.stream()
             .filter(o2 -> mapCodes.containsKey(o2.getCode()))
             .forEach(o2 -> mapCodes.get(o2.getCode())
                                    .forEach(o1 -> binarySomething(o1, o2)));

Si les deux object1 et object2 sont consommés dans une méthode comme:

static void binarySomething(Object1 o1, Object2 o2) {
}

une carte de codes Map<Integer, List<Object1>> mapCodes peut être créée en utilisant groupingBy , puis appliquer le filter et forEach :

class MyClass {
    static void process(List<Object1> listOfObject1, List<Object2> listOfObject2) {

        // set of codes for Object1 instances
        Set<Integer> codes = listOfObject1.stream()
                                          .map(Object1::getCode)
                                          .collect(Collectors.toSet());
        listOfObject2.stream()
                     .filter(o2 -> codes.contains(o2.getCode()))
                     .forEach(MyClass::unarySomething);  // method reference
    }

    static void unarySomething(Object2 o2) {
    }
}


0 commentaires