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.
3 Réponses :
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é
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); } }
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:
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; }
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; }