J'ai une liste d'utilisateurs dans un magasin local que je dois mettre à jour à partir d'une liste distante d'utilisateurs de temps en temps. Fondamentalement:
par exemple. Liste à distance: utilisateur (1, true), utilisateur (2, true), utilisateur (4, true), utilisateur (5, true) p>
Liste locale: utilisateur (1, true), utilisateur (2 , faux), utilisateur (3, true), utilisateur (6, true) p>
nouvelle liste locale: utilisateur (1, true), utilisateur (2, true), utilisateur (3, false), utilisateur (4, True), utilisateur (5, true), utilisateur (6, faux), p>
juste un cas simple de synchronisation de la liste locale. Y a-t-il un meilleur moyen de le faire dans Pure Java que ce qui suit? Je me sens grossièrement en regardant mon propre code. P>
public class User { Integer id; String email; boolean active; //Getters and Setters....... public User(Integer id, String email, boolean active) { this.id = id; this.email = email; this.active = active; } @Override public boolean equals(Object other) { boolean result = false; if (other instanceof User) { User that = (User) other; result = (this.getId() == that.getId()); } return result; } } public static void main(String[] args) { //From 3rd party List<User> remoteUsers = getRemoteUsers(); //From Local store List<User> localUsers =getLocalUsers(); for (User remoteUser : remoteUsers) { boolean found = false; for (User localUser : localUsers) { if (remoteUser.equals(localUser)) { found = true; localUser.setActive(remoteUser.isActive()); localUser.setEmail(remoteUser.getEmail()); //update } break; } if (!found) { User user = new User(remoteUser.getId(), remoteUser.getEmail(), remoteUser.isActive()); //Save } } for(User localUser : localUsers ) { boolean found = false; for(User remoteUser : remoteUsers) { if(localUser.equals(remoteUser)) { found = true; localUser.setActive(remoteUser.isActive()); localUser.setEmail(remoteUser.getEmail()); //Update } break; } if(!found) { localUser.setActive(false); // Deactivate } } }
3 Réponses :
Vous pouvez utiliser list.indexof () code> au lieu d'itération via la liste:
for (User remoteUser : remoteUsers) {
int index = localUsers.indexOf(remoteUser);
if (index >= 0) {
User localUser = localUsers.get(index);
localUser.setActive(remoteUser.isActive());
localUser.setEmail(remoteUser.getEmail());
//update
} else {
User user = new User(remoteUser.getId(), remoteUser.getEmail(), remoteUser.isActive());
//Save
}
}
Mais sans compréhension ou itération de la liste, comment puis-je obtenir les paramètres de mise à jour?
Variable localUser indéfini?
Le meilleur moyen est de passer à une autre structure de données. Un IMPORTANT: vous Donc, disons que vous avez 1.) Si un utilisateur distant existe déjà localement, mettez à jour ses champs. Recherche si un mappe
mappe code> peut être un
hashmap code> (attendu
O (1) code> pour les opérations de base) ou un
treemap code > (
O (journal n) code>).
@override est égal (objet) code> sans
@override hashcode () code> !! ! C'est
mappe
et
plan
4.) Si un utilisateur local apparaît également dans la liste distante, mettez à jour ses champs. frappe> (identique 1)
2.) Si un utilisateur distant n'existe pas déjà localement, ajoutez l'utilisateur. p>
blockQquote> utilisateur code> à partir de
est dans code> est dans
localusers code> peut être répondu dans
o (1) Code> ou
O (journal n) code> avec un simple
contenant de la carte code> et
obtenez code>. p>
Set<Integer> toDeactivate = new TreeSet<Integer>();
toDeactivate.addAll(localUsers.keySet());
toDeactivate.removeAll(remoteUsers.keySet());
for (int id : toDeactivate) {
User local = localUsers.get(id);
local.deactivate();
localUsers.remove(id);
}
Il n'est pas toujours possible de basculer entre Liste code> et
définir code>. Cela dépend du modèle de domaine.
Vous pouvez toujours utiliser définir code> en tant qu'intermédiaire. Il est toujours plus rapide parce que c'est
O (n) code> ou
O (n journal n) code> comme s'y oppose à
O (n ^ 2) code>.
Voir la ligne ci-dessus: local = localusers.get (distant); list.get seulement prend un index entier non obj.
@Langali, ce code est pour quand localusers code> et
users code> est
définit
list
Ok, j'ai réalisé que définir code> n'a pas de
obtenez code>, donc je suis passé sur
plan code>, ce qui a plus de sens de toute façon.
Langali:
En supposant que l'ID identifie de manière unique un utilisateur, j'ai quelques suggestions pour vous: p>
Obtenir code> et Containte de contenant code> pour rechercher ce que vous recherchez. LI>
ul> Le problème avec la liste.Contains est que, sur une arracheListe, il effectue une analyse complète du contenu de la liste. Si vous le faites pour chaque article d'une deuxième liste, votre performance est O (N ^ 2), ce qui signifie que lorsque vous doublez les éléments que vous multipliez par quatre temps requis pour exécuter votre méthode. Un hashmap a une performance de O (journal (n)), ce qui signifie que si vous êtes 1000 objets, le temps nécessaire à l'exécution est juste 10 fois plus lent (environ). P> p>
1 et 4 doivent être faits qu'une seule fois, ils sont la même chose
Vous pouvez extraire des méthodes (comme
update (utilisateur utilisateur) code> Intérieur
utilisateur code> qui définirait les champs de
utilisateur code> sur
ceci code>). Vous pouvez également utiliser
java.util.collections.binginationSearch (liste, utilisateur) code> à l'intérieur des compréhensions.