Скопируйте значение из одного списка в другой объект, который может быть однозначно идентифицирован ключом карты - PullRequest
0 голосов
/ 14 января 2020

У меня есть карта типа Map<Long, Long>. Ключ представляет собой уникальный идентификатор Employee. Значение представляет количество времени, которое он работал. У меня тоже есть List<ProjectEmployee>. ProjectEmployee определяется следующим образом:

public class ProjectEmployee {

  private Employee employee;
  private Project project;
  private Long workTime;
}

Всегда есть только один ProjectEmployee на сотрудника. Таким образом, ProjectEmployee может быть однозначно идентифицирован его сотрудником.

Теперь я хочу скопировать значение, сохраненное на карте, в workTime из ProjectEmployee, идентификатор сотрудника которого равен ключу карты , Так, например, если на карте есть пара 10=>20, я хотел бы найти ProjectEmployee, чей сотрудник имеет идентификатор 10 и установить для поля workTime этого ProjectEmployee значение 20.

Я хотел бы знать, есть ли способ сделать это менее чем за O (n ^ 2). Наивный подход, о котором я думаю, состоит в том, чтобы перебирать всю карту и внутри l oop, перебирать все ProjectEmployees, пока я не найду тот, который ищет текущую пару карт, а затем скопировать поле.

Предположим, что каждый ключ идентификатора сотрудника внутри Map<Long, Long> содержит ровно один ProjectEmployee, с которым он может быть сопоставлен в данном списке.

Ответы [ 2 ]

2 голосов
/ 14 января 2020

Что-то вроде:

projectEmployees.forEach(pe -> pe.setWorkTime(map.get(pe.getEmployee().getId())));

Возможно, с проверкой, map.containsKey.

Конечно, если карта представляет собой небольшую часть сотрудников проекта, вам понадобится отображение ID для сотрудников проекта.

1 голос
/ 14 января 2020

Вы можете сделать это за O (n) время довольно легко, с помощью O (n) вспомогательного пространства: начните с построения Map<Long, ProjectEmployee> из вашего списка, где ключом является ProjectEmployee объект employee. Идентификационный номер. Затем во втором l oop используйте карту для получения ProjectEmployee объектов по ID за O (1) раз каждый.

Это может выглядеть примерно так:

// stage 1: build a map
Map<Long, ProjectEmployee> byId = new HashMap<>();
for(ProjectEmployee p : employeeList) {
    byId.put(p.employee.id, p);
}

// stage 2: do the updates
for(Map.Entry<Long, Long> e : workTimeMap.entrySet()) {
    ProjectEmployee p = byId.get(e.getKey());
    p.workTime = e.getValue();
}

В зависимости от того, для чего вам еще нужны объекты ProjectEmployee, может иметь смысл сохранять их на карте, а не в списке.

...