Используя Java 8 Steam, чтобы найти совпадающие строки между двумя списками и сопоставить с другим объектом - PullRequest
0 голосов
/ 14 октября 2018

Я пытаюсь найти соответствующий элемент между двумя различными списками, а затем я пытаюсь сопоставить со списком различных объектов, который содержит элементы из списка некоторых выбранных элементов.

Вот мои два боба -

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;
}

Как получить окончательный список, содержащий совпадениес correlationId, eventDate и в результате я хотел список ResultBean.

Может кто-нибудь помочь, пожалуйста?

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 14 октября 2018

После комментария Луи Вассермана можно было бы использовать потоки там, где у него есть преимущество.Подумайте о том, чтобы LogsData и DistributionData (и, необязательно, ResultBean) расширяли базовый тип:

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() );
    }
}

Данные для списка:

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

Вы можете пересечь два списка просто

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

Сортируйте их в том же порядке:

//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()));

и используйте Stream для построения списка ResultBean объектов:

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());
0 голосов
/ 15 октября 2018

Я немного изменил дизайн, чтобы он работал, я добавил список рассылки в Logs Beans, так как он имеет отношение один ко многим, я могу комбинировать данные из обоих списков, но он работает очень медленно, так как размер коллекции довольноБольшой, особенно список рассылки, может кто-нибудь предложить что-то высокоэффективное или лучший дизайн.

 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()); 
0 голосов
/ 14 октября 2018

Один из подходов состоит в том, чтобы накапливать элементы списка logsData в карте, где ключ logsData#getEventDate объединяется с logsData#getCorrelationId.

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

, а затем передается по списку distributionDataи получить соответствующие элементы на карте, а затем преобразовать их в 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());

, что предполагает, что ResultBean имеет конструктор, принимающий все необходимые аргументы, если это не так, тогда просто вызовите установщикметоды для установки необходимых данных.

import:

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

другой подход, хотя и менее эффективный:

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());

немного другой, в JDK9 во избежание .orElse(null)).filter(Objects::nonNull)шаблон:

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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...