Выбор сложности времени исполнения алгоритма для обновления данных между двумя коллекциями

Есть 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() в этом случае ?


Ответы (0 шт):