Liste Java avec des objets - rechercher et remplacer l'entrée (supprimer) si l'objet avec certains attribut existe déjà

StackOverflow https://stackoverflow.com/questions/2470329

Question

Je travaille toute la journée et je ne peux pas obtenir en quelque sorte cette tâche probablement facile a compris - sans doute un manque de café ...

J'ai un synchronizedList où certains objets sont stockés. Ces objets ont une field qui est quelque chose comme une carte d'identité. Ces objets portent des informations sur un utilisateur et son état actuel (simplifié).

Le point est que je veux qu'un seul objet pour chaque utilisateur. Ainsi, lorsque l'état de ce changement d'utilisateur, je voudrais supprimer l'entrée « ancienne » et stocker un nouveau dans le List.

protected static class Objects{
    ...
    long time;
    Object ID;
    ... 
    }

...

if (Objects.contains(ID)) {
            Objects.remove(ID);
            Objects.add(newObject);
        } else {
            Objects.add(newObject);
        }

Il est évident que ce n'est pas la voie à suivre, mais devrait illustrer ce que je cherche ...
Peut-être que la structure de données ne sont pas le meilleur à cet effet, mais toute aide est la bienvenue!


EDIT:
Ajout d'informations ...
Un Set ne semble pas vraiment adapter mon but. Le Objects stocker d'autres domaines que l'ID qui changent tout le temps. Le but est que la liste représentera en quelque sorte les dernières activités d'un utilisateur. Je dois seulement suivre le dernier état et ne garder que cet objet qui décrit cette situation.
Je pense que je vais essayer réarranger mon code avec un Map et voir si cela fonctionne ...

Était-ce utile?

La solution

Une carte est plus facile, mais un ensemble reflète mieux votre logique. Dans ce cas, je conseille un ensemble.

Il y a 2 façons d'utiliser un ensemble, en fonction des égaux et hashCode de votre objet de données.

Si YourObject utilise déjà l'objet d'ID pour déterminer égaux (et hashCode obéisse le contrat), vous pouvez utiliser l'ensemble que vous voulez, un HashSet est probablement mieux alors.

Si YourObjects logique métier nécessite un différents égaux, en prenant en compte plusieurs champs à côté du champ d'ID, puis un comparateur personnalisé doit être utilisé. Un TreeSet est un ensemble qui peut utiliser une telle comparaison.

Un exemple:

Comparator<MyObject> comp = new Comparator<MyObject>{
  public int compare(MyObject o1, MyObject o2) {
    // NOTE this compare is not very good as it obeys the contract but
    // is not consistent with equals. compare() == 0 -> equals() != true here
    // Better to use some more fields
    return o1.getId().hashCode() < o2.getId().hashCode();
  }
  public boolean equals(Object other) {
    return 01.getId().equals(o2.getId());
  }
}

Set<MyObject> myObjects = new TreeSet(comp);

EDIT J'ai mis à jour le code ci-dessus pour indiquer que id n'est pas un entier, comme le suggère la question.

Autres conseils

Vous pouvez utiliser un HashMap (ou LinkedHashMap / TreeMap si l'ordre est important) avec une clé d'identité et d'une valeur d'objets. Avec les médicaments génériques qui seraient HashMap<Object, Objects>();

Ensuite, vous pouvez utiliser

if (map.containsKey(ID)) {
    map.remove(ID);
}

map.put(newID, newObject);

Sinon, vous pouvez continuer à utiliser une liste, mais nous ne pouvons pas modifier simplement la collection tout en réitérant, donc au lieu que nous pouvons utiliser un itérateur pour supprimer l'élément existant, puis ajouter le nouvel élément en dehors de la boucle (maintenant vous êtes sûr que l'ancien article a disparu):

List<Objects> syncList = ...

for (Iterator<Objects> iterator = syncList.iterator(); iterator.hasNext();) {
    Objects current = iterator.next();

    if (current.getID().equals(ID)) {
        iterator.remove();
    }
}

syncList.add(newObject);

Et vous ne pouvez pas utiliser un Set pour avoir seul le premier stocké?

parce qu'il est fondamentalement exactement ce dont vous avez besoin.

Vous pouvez utiliser un HashSet pour stocker les objets et remplacer la méthode hashCode dans la classe que le HashSet contiendra retourner le hashcode de votre champ d'identification.

Ma première option serait un HashSet , il faudrait que vous remplacer le hashCode et égal méthodes (ne pas oublier: si vous substituez une, remplacer systématiquement l'autre!) afin que les objets avec le même identifiant sont considérés comme égaux.

Mais cela pourrait casser quelque chose si cette hypothèse est de ne pas être fait dans d'autres parties de votre application. Dans ce cas, vous pouvez opter pour l'utilisation d'un HashMap (avec l'ID comme clé) ou mettre en œuvre votre propre MyHashSet classe (soutenu par un HashMap ).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top