0
votes

Quelle sera la meilleure façon d'itérer la liste selon la logique métier du point de vue des performances pour l'exigence décrite ci-dessous

J'ai une liste d'entités. ce sont la réponse de db. J'ai une autre liste de longue. Dans la liste des entités, chaque objet entité a un champ appelé id. Ces identifiants seront toujours dans l'ordre croissant.Je dois parcourir la liste d'entités selon l'ordre donné dans la liste de long. J'ai également besoin de maintenir une autre liste d'objet de réponse qui contiendra peu de champs de plus que ce que nous avons dans la liste d'entités. Je ne peux pas utiliser de transitoire également. Le code ci-dessous vous donnera une idée.

public List<ResponseObject> convert(List<EntityObject> entityList, List<Long> orderedIdList) {

    List<ResponseObject> responseList = new ArrayList<>();
    for (EntityObject object : entityList) {
        ResponseObject responseObject = new ResponseObject();
        responseObject.someSettermethod(object.someGettermethod());
        /* other setters in responseObject which are not present in the entity object */
        responseObject.otherSetters("some value"); 
        responseList.add(responseObject);
    };
    return sortInOrder(responseList, orderedIdList);
}

private List<ResponseObject> sortInOrder(List<ResponseObject> responseList,List<Long> orderedIdList) {
    List<ResponseObject> finalList = new ArrayList<>();
     for(Long id : orderedIdList){
         for(ResponseObject response : responseList){
             if(response.getId().equals(id)){
                 finalList.add(response);
             }
         }
     }
    return finalList;
}

Voici comment il a été implémenté pour le moment. J'aimerais savoir s'il existe une meilleure approche pour améliorer les performances afin d'obtenir le même résultat.


0 commentaires

3 Réponses :


2
votes

Si ces listes ne sont pas énormes (comme dans plusieurs milliers d'entrées), je ne m'inquiéterais pas des performances. C'est raisonnable comme cela est et tant que vous n'échouez pas à des exigences de performances spécifiques, vous ne devriez pas optimiser votre code pour les performances de toute façon. Vous pouvez par contre optimiser votre code pour la lisibilité

  • en utilisant un comparateur pour trier votre liste
  • en utilisant l'API streams pour réduire la profondeur de vos méthodes.

Le comparateur pourrait être construit en utilisant la liste de classement et en comparant ensuite les indices des identifiants de votre resultList.

Le comparateur pourrait ressembler à celui-ci:

private static class IndexComparator implements Comparator<Long> {
    private final List<Long> order;

    private IndexComparator(List<Long> order) {
        this.order = order;
    }

    @Override
    public int compare(Long id1, Long id2) {
        return Comparator.comparingLong(order::indexOf).compare(id1, id2);
    }
}


0 commentaires

2
votes

La méthode sortInOrder peut être effectuée plus rapidement que O (N ^ 2):

En supposant que les identifiants sont uniques (faites-moi savoir si c'est une mauvaise hypothèse):

Idée:

  1. Créez un mappage de l'ID à responseObject en itérant sur la liste de réponses O (n).
  2. Parcourez la liste commandéeIdList et vérifiez l'identifiant dans la carte, si l'identifiant existe, ajoutez la valeur à l'objet de réponse.
private List<ResponseObject> sortInOrder(List<ResponseObject> responseList,List<Long> orderedIdList) {
    List<ResponseObject> finalList = new ArrayList<>();
    Map<Long, ResponseObject> map = responseList.stream().collect(Collectors.toMap(ResponseObject::getId, respObj -> respObj));
    for(Long id : orderedList) {
      if(map.containsKey(id)) {
         finalList.add(map.get(id));
      }
    }
    return finalList;
}


0 commentaires

1
votes

Si vous utilisez map au lieu d'une liste comme ci-dessous, vous pouvez le faire avec la complexité O (n) au lieu de O (n2)

public List<ResponseObject> convert(List<EntityObject> entityList, List<Long> orderedIdList) {

        Map<Long, ResponseObject> responseMap = new HashMap<Long, ResponseObject>();
        for (EntityObject object : entityList) {
            ResponseObject responseObject = new ResponseObject();
            responseObject.someSettermethod(object.someGettermethod());
            /* other setters in responseObject which are not present in the entity object */
            responseObject.otherSetters("some value");
            responseMap.put(responseObject.getId(), responseObject);
        };
        return sortInOrder(responseMap, orderedIdList);
    }

    private List<ResponseObject> sortInOrder( Map<Long, ResponseObject> responseMap, List<Long> orderedIdList) {
        List<ResponseObject> finalList = new ArrayList<>();
        for(Long id : orderedIdList){
            finalList.add(responseMap.get(id));
        }
        return finalList;
    }


0 commentaires