Выбор сложности времени исполнения алгоритма для обновления данных между двумя коллекциями
Есть 2 коллекции, тип List (коллекции могут быть разных типов), но на данный момент список принят в качестве отправной точки.
- pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-random-core</artifactId>
<version>5.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Эти коллекции построены на основе 2-х объектов :
- NodeNewData
- Node
public class Node {
private String idNode;
private NodePosition nodePosition;
private String nameNode;
//getters and setters
}
public class NodePosition {
private double xPos;
private double yPos;
private double zPos;
//getters and setters
}
public class NodeNewData {
private String idNode;
private NodePosition nodePosition;
Для каждого объекта существует коллекция, которая является входной для обработки запроса.
коллекция List будет состоять из 3000 записи.
коллекция List будет состоять из 10 - 100 записи (редко 1000).
Нам нужно, чтобы данные из List( а именно только Node Position), обновили каждый узел в List, то есть для конкретного узла, в соответствии с idNode этого узла.
В качестве примера я использовал 2 вложенных цикла
public class CollectionChange {
private List<Node> nodeList;
private List<NodeNewData> nodePositionList;
public CollectionChange(List<Node> nodeList, List<NodeNewData> nodePositionList) {
this.nodeList = nodeList;
this.nodePositionList = nodePositionList;
}
public void runChangeBetweenCollectionON2(){
nodeList.forEach(nodeTarget -> {
nodePositionList
.stream()
.filter(nodeWithNewPosition -> nodeWithNewPosition.getIdNode()
.equals(nodeTarget.getIdNode()))
.forEach(
nodeWithNewPosition -> nodeTarget.setNodePosition(nodeWithNewPosition.getNodePosition())
);
});
}
}
- Тестовый контур
class CollectionChangeTest {
private static CollectionChange collectionChange;
@BeforeAll
static void setup() {
int countObjects = 3000;
final List<Node> nodeList = fillList(Node.class, countObjects);
countObjects = 100;
final List<NodeNewData> nodePositionList = fillList(NodeNewData.class, countObjects);
collectionChange = new CollectionChange(nodeList, nodePositionList);
}
private static <T> List<T> fillList (Class<T> clazz, int countObjects){
EasyRandom generator = new EasyRandom();
return generator
.objects(clazz, countObjects)
.collect(Collectors.toList());
}
@Test
void runChangeBetweenCollectionON2() {
Instant startProcessRequest = Instant.now();
collectionChange.runChangeBetweenCollectionON2();
Instant finishProcessRequest = Instant.now();
long resultTimeOfProcessRequest = Duration
.between(startProcessRequest,finishProcessRequest)
.toSeconds();
outputResult(resultTimeOfProcessRequest);
}
private void outputResult(long resultTimeOfProcessRequest){
String messageInfoFirst = "Request processing time";
String messageInfoSecond = " seconds.";
final String formatMessageInfo = String.format("%s : %d %s", messageInfoFirst,
resultTimeOfProcessRequest, messageInfoSecond);
System.out.println(formatMessageInfo);
}
}
Временная сложность этого алгоритма (обновление данных между двумя коллекциями) составляет O (n^2), как я предполагаю (из-за 2 вложенных циклов).
Надо сказать , что коллекции приходят в формате List (в качестве реализации стоит - ArrayList).
Можете ли вы предложить алгоритмы оптимизации для этой задачи, чтобы уменьшить сложность времени выполнения ?
В чем преимущество filter() в этом случае, то есть влияет ли он на сложность времени выполнения?
Было предложено использовать меньшую коллекцию в качестве ведущей. Изменится ли сложность времени выполнения? ( На мой взгляд - это будет дольше)?
Насколько уместно использование parallelsStream() в этом случае ?