Как эффективно объединить два списка по id в Java 7? - PullRequest
0 голосов
/ 28 февраля 2020

У меня проблема с получением двух списков объектов и их эффективным объединением, чтобы по существу создать третью модель данных, которая возвращается в конечной точке моего API. Одна из проблем заключается в том, что я получаю список сущностей [Сотрудники] из одной базы данных, а затем я получаю другой список сущностей [ClockedIn] из другой базы данных, так что это выглядит так:

class Employee {
  private Integer employeeID;
  private String firstName;
  private String lastName;
  etc...

  //corresponding getters and setters
}

и

class ClockedIn {
  private Integer employeeID;
  private Date timeStamp;
  etc...

//corresponding getters and setters

} 

Для присоединения сейчас я делаю это следующим образом:

List<Employee> getEmployees = repository.getAll();
List<ClockedIn> getClockedIn = repository.getAll();
List<JoinedDataModel> joinedDataModelList = new ArrayList<JoinedDataModel>();

for(Employee emp : getEmployees) {
    JoinedDataModel joinDataModel = new JoinedDataModel();
    int currentId = empt.getEmployeeId();
    List<Dates> missingClockedIn = new ArrayList<Dates>();
    for(ClockedIn ci : getClockedIn) {
        if(currentId == ci.getEmployeeId) {
            // add together to the third datamodel
            joinDataModel.setId();
            if(missingDate(ci.getTimeStamp()) {
                missingClockedIn.add(ci.getTimeStamp());
            }
        }
        joinDataModel.setMissingClockedIn(missingClockedIn);
    }
}
joinedDataModelList.add(joinDataModel);

У меня около 70 тыс. Элементов в ClockedIn-списке и 1400 в Employee-List, и для вычисления требуется около 15 секунд , но следует учитывать, что мне нужно получить данные из двух разных баз данных. Однако, если я добавлю 10k к списку ClockedIn, сервер истекает по тайм-ауту, я не настолько хорошо разбираюсь в нотации Big O, но я думаю, что способ, которым я его настроил сейчас, довольно тяжелый из-за вложенных циклов, я думаю, что это O (n2)?

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

Любые входные данные на моя реализация выше будет принята с благодарностью!

Спасибо!


* Отказ от ответственности, все это псевдокод, поэтому любая синтаксическая ошибка или что-то подобное найдено в коде размещенные здесь не имеют отношения к моей проблеме.

1 Ответ

1 голос
/ 28 февраля 2020

Основная идея c состоит в том, что вы собираетесь просмотреть коллекцию ClockedIn и организовать их в ArrayLists, к которым можно легко получить доступ с помощью значения EmployeeId. Это делается с помощью объекта HashMap, который может использовать EmployeeId в качестве ключа для быстрого доступа. Пример:

//Class declaration for example use
class Employee {
    int employeeId;
    //Plus any other info
    Employee(int employeeId) {
        this.employeeId = employeeId;
    }
}

class ClockedIn{
    int employeeId;
    //Plus any other info
    ClockedIn(int employeeId) {
        this.employeeId = employeeId;
    }
}

//Data creation for example use
private List<Employee> getEmployeeData() {
    List<Employee> data = new ArrayList<>();
    for(int i = 0; i < 50; i++) {
        data.add(new Employee(i));
    }
    return data;
}

private List<ClockedIn> getClockedInData() {
    List<ClockedIn> data = new ArrayList<>();
    for(int i = 0; i < 1000; i++) {
        data.add(new ClockedIn(i % 50));
    }
    return data;
}

//Actual hashmapping and combining
private void hashmap() {
    HashMap<Integer, ArrayList<ClockedIn>> map = new HashMap<>();

    for(ClockedIn data : getClockedInData()) {
        if(map.get(data.employeeId) == null)
            map.put(data.employeeId, new ArrayList<ClockedIn>());
        map.get(data.employeeId).add(data);
    }

    for(Employee data : getEmployeeData()) {
        ArrayList<ClockedIn> relatedClockData = map.get(data.employeeId);
        //Combine the Employee data with the related ClockedIn data here
    }
}
...