web-dev-qa-db-fra.com

Java 8 Lambda - Intersection de deux listes

J'essaie de trouver intersection de deux listes en fonction de certaines conditions et de certaines étapes. Impossible de trouver un moyen de le faire (en phase d'apprentissage) :)

Double totalAmount = 0.00d;
Double discount = 0.00d;


List<OrderLineEntry> orderLineEntryList = orderEntry.getOrderReleases().stream()
    .flatMap(orderReleaseEntry -> orderReleaseEntry.getOrderLines().stream())
    .filter(orderLineEntry -> orderLineEntry.getStatus().equals("PP") || orderLineEntry.getStatus().equals("PD"))
    .collect(Collectors.toList());

for (OrderLineEntry orderLineEntry : orderLineEntryList) {
    for (SplitLineEntry splitLineEntry : splitReleaseEntry.getLineEntries()) {
        if (splitLineEntry.getOrderLineId().equals(orderLineEntry.getId()) && splitLineEntry.getStatusCode() != "PX") {
            totalAmount += orderLineEntry.getFinalAmount();
            couponDiscount += orderLineEntry.getCouponDiscount() == null ? 0.00d : orderLineEntry.getCouponDiscount();
        }
    }
}

Comme vous le voyez, la logique est simple

Obtenez Tous les éléments de l'ordre en fonction d'un filtre list et intersectez-les avec un autre list et effectuez des opérations.

37
Reddy

L'approche la plus simple est la suivante:

List<T> intersect = list1.stream()
                         .filter(list2::contains)
                         .collect(Collectors.toList());
114
Silas Reinagel

Je dois les comparer sur supposer list1.id == list2.fk_id

Commencez par créer un ensemble de fk_id;

Set<Integer> orderLineEntrSet = orderEntry.getOrderReleases().stream()
    .flatMap(orderReleaseEntry ->
orderReleaseEntry.getOrderLines().stream())
    .filter(orderLineEntry -> { 
            String s = orderLineEntry.getStatus(); 
            return "PP".equals(s) || "PD".equals(s); 
    })
    .map(e -> e.getId())
    .collect(Collectors.toSet());

double[] totalAmount = { 0.0 };
double[] couponDiscount = { 0.0 };
orderLineEntryList.stream()
    .flatMap(sre -> sre.getLineEntries().stream())
    .filter(ole -> orderLineEntrySet.contains(ole.getOrderLineId())
    .filter(ole -> !"PX".equals(ole.getStatusCode()))
    .forEach(ole -> {
            totalAmount[0] += ole.getFinalAmount();
            if (ole.getCouponDiscount() != null)
                couponDiscount[0] += ole.getCouponDiscount();
        });

Vous pouvez éviter d'utiliser une référence à un objet de tableau en utilisant la fonction de réduction. par exemple. voyez comment Collectors.averagingDouble est implémenté. Mais je trouve cela plus compliqué.

Remarque: il s’agit de O(N)) en utilisant un ensemble d’id (id) plutôt qu’en utilisant une liste d’ID correspondants, qui seraient O (N ^ 2).

11
Peter Lawrey