Using java 8 steam to find matching rows between two list and map to another object

how to get values from list object in java 8
modify property value of the objects in list using java 8 streams
java 8 compare two lists of objects
java 8 filter list based on another list
how to compare two arraylist of different objects in java
java-stream find all matches
java 8 compare two lists and find differences
java stream filter two lists

I am trying to find matching element between two different lists and then I am trying to map to list of different object which contains the elements from both the list some selected elements.

Here are my two beans -

public class LogsData {
    LocalDate eventDate ;
    String correlationId;
    String authId;
    int numberofSQL;
    // getter and setter
}

public class DistributionData {
    LocalDate eventDate;
    String correlationId;
    String callingProId;
    long transactionCount ;
    // getter and setter 
}

public class ResultBean {
    LocalDate eventDate;
    String correlationId;
    String callingProId;
    long transactionCount ;
    String authId ;
    int numberOfSQL;
}

How do I get a final list which contains a match with correlationId , eventDate and in the result, I wanted List of ResultBean.

Can somebody please assist?

Thanks in advance.

one approach would be to accumulate the elements of the logsData list into a map where the key is logsData#getEventDate concatenated with logsData#getCorrelationId.

Map<String, LogsData> accumulator = 
        logsData.stream()
                .collect(toMap(l -> l.getEventDate() + l.getCorrelationId(), Function.identity()));

then stream over the distributionData list and get the corresponding elements in the map and then transform them into a ResultBean.

List<ResultBean> resultSet = distributionData.stream()
       .map(d -> {
              LogsData logs = accumulator.get(d.getEventDate() + d.getCorrelationId());
              if (logs != null)
                   return new ResultBean(d.getEventDate(), d.getCorrelationId(),
                     d.getCallingProId(), d.getTransactionCount(), logs.getAuthId(), logs.getNumberofSQL());
                 return null;
       })
       .filter(Objects::nonNull)
       .collect(Collectors.toList());

this assumes ResultBean has a constructor taking all the necessary arguments if that's not the case then just call the setter methods to set the necessary data.

imports:

import static java.util.stream.Collectors.*;
import java.util.stream.*;
import java.util.function.*;

another approach although less efficient:

List<ResultBean> resultSet = logsData.stream()
                .map(l -> distributionData.stream()
                        .filter(d -> l.getEventDate().equals(d.getEventDate()) &&
                                l.getCorrelationId().equals(d.getCorrelationId()))
                        .findFirst()
                        .map(d -> new ResultBean(d.getEventDate(), d.getCorrelationId(),
                                d.getCallingProId(), d.getTransactionCount(), l.getAuthId(), l.getNumberofSQL()))
                        .orElse(null))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

slightly different, in JDK9 in avoiding the .orElse(null)).filter(Objects::nonNull) pattern:

List<ResultBean> resultSet = logsData.stream()
                .flatMap(l -> distributionData.stream()
                        .filter(d -> l.getEventDate().equals(d.getEventDate()) &&
                                l.getCorrelationId().equals(d.getCorrelationId()))
                        .findFirst()
                        .map(d -> new ResultBean(d.getEventDate(), d.getCorrelationId(),
                                d.getCallingProId(), d.getTransactionCount(), l.getAuthId(), l.getNumberofSQL()))
                        .stream()
                )
                .collect(Collectors.toList());

Learn how to use data from one stream to find items in another. 2. Using Java 8 Streams. Let's start with two entity classes – Employee The idea here is to filter a list of Employee objects based on a list of Department objects. Next, to filter records based on our two conditions, we're using the anyMatch  The Java 8 Stream API introduced two methods that are often being misunderstood: findAny () and findFirst (). In this quick tutorial, we will be looking at the difference between these two methods and when to use them. A quick and practical guide to using Java 8 Streams with primitive types. As the name suggests, the findAny () method allows

Following Louis Wasserman's comment it might be possible to use Streams where it has an advantage. Consider having LogsData and DistributionData (and optionally ResultBean) extend a base type:

class Data {

    LocalDate eventDate ;
    String correlationId;

    Data(LocalDate eventDate, String correlationId) {
        this.eventDate = eventDate;
        this.correlationId = correlationId;
    }

    LocalDate getEventDate() { return eventDate; }
    String getCorrelationId(){ return correlationId; }

    @Override
    public boolean equals(Object o) {
        if(!(o instanceof Data)) { return false; }
        Data d = (Data) o;
        return eventDate.equals(d.getEventDate())
                && correlationId.equals(d.getCorrelationId() );
    }
}

Given to list :

List<LogsData> logsData = new ArrayList<>();
List<DistributionData> dData = new ArrayList<>();

You could intersect two lists simply by

logsData.retainAll(dData);
dData.retainAll(logsData);

Have them sorted at the same order :

//sort so two lists have the same order. If correlationId is not unique you may need 
//to enhance the comperator 
Collections.sort(dData, (a, b) -> a.getCorrelationId().compareToIgnoreCase(b.getCorrelationId()));
Collections.sort(logsData, (a, b) -> a.getCorrelationId().compareToIgnoreCase(b.getCorrelationId()));

and use Stream to construct a List of ResultBean objects:

List<ResultBean> resultList = IntStream.range(0, logsData.size())
    .mapToObj( i ->
            new ResultBean(dData.get(i).getEventDate(), dData.get(i).getCorrelationId(),
            dData.get(i).getCallingProId(), dData.get(i).getTransactionCount(),
            logsData.get(i).getAuthId(), logsData.get(i).getNumberofSQL())
            )
    .collect(Collectors.toList());

Example of different kinds of streams in Java 8 [Part 2] the criteria, Java 8 Streams allow declarative matching of objects in the stream. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more How to get a range of items from stream using Java 8 lambda?

I changed little bit design to make it to work , I added Distribution List into Logs Beans as it has one to many relationship , i am able to combine data from both list but it is running very slow as the collection size is quite large especially the Distribution list , can somebody please suggest something highly performant or any better design .

 List<LogsData> logsData = logs.stream()
            .filter(e -> (distributionData.stream()
                    .filter(d -> 
           d.getCorrelationId.equals(e.getCorrelationId))
       .filter(d-> d.getEventDate().equals(e.getEventDate()))
       .map(mapper-> e.getDistribution().add(mapper); return e; })
                    .count())<1)
                    .collect(Collectors.toList()); 

and non matching records with multiple filter predicates in Java8 Streams Using streams I'm able to find the matching and non matching Map; import java​.util.stream. currentTimeMillis(); List<Map<String, Object>> dbRecords combine a linear search with another linear search; with the resulting  In Java 8, stream().map() lets you convert an object to something else. Review the following examples : 1. A List of Strings to Uppercase. 1.1 Simple Java example to convert a list of Strings to upper case.

Combine advanced operations of the Stream API to express rich data Part 2: Processing Data with Java SE 8 Streams flatMap : An intermediate operation that lets you combine a “map” and a “flatten” For example, to get a list of the IDs for all the expensive transactions, you can use What does a Collector object do​? Create a list of the Hosting objects, and uses Collectors.toMap to convert it into a Map. TestListMap.java. package com.mkyong.java8 import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class TestListMap { public static void main (String [] args) { List<Hosting> list = new

By the way, you can get Stream not just from the Collection but from other sources to use Java 8 Stream API with simple * examples like filter objects, transforming objects match the predicate, count() - which counts the number of items in a stream, Java 8 Map Example 2: Create List of the square of all distinct numbers. Java 8 stream distinct by multiple fields example. Learn to find distinct objects from a stream by comparing multiple fields or creating a custom key class.

We would be using contains() method for comparing two elements of different Algorithm – find intersection or join point of two single linked lists in java Jul Sorting a Java list collection in the classic way java code to compare two hash map objects. Aug 26, 2019 · Joining Objects into a String with Java 8 Stream API. int  Java 8 – Map To List. For Java 8, you can convert the Map into a stream, process it and returns it back as a List

Comments
  • This is almost certainly going to be much easier if you don't bother using streams.
  • Can be more than one element with the same (eventDate, correlationId) in logs data list? Same for distribution data list. If yes, if there are i.e. 2 duplicates in the logs list and 3 duplicates in the distribution list, all with the same (eventDate, correlationId) through both lists, do you expect the result to contain all the possible combinations, i.e. 6 elements?