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érieurutilisateur code> qui définirait les champs deutilisateur code> surceci code>). Vous pouvez également utiliserjava.util.collections.binginationSearch (liste, utilisateur) code> à l'intérieur des compréhensions.