7
votes

Comptez les occurrences d'articles dans ArrayList

J'ai un java.util.arraylist et un objet objet objet.

Maintenant, je veux obtenir le nombre de fois que l'élément est stocké dans la liste ArrayList.

Je sais que je peux faire arraylist.contains () vérifier, mais il renvoie true, que cela contienne une ou plusieurs objets s.

Q1. Comment puis-je trouver le nombre de temps que l'élément est stocké dans la liste?

Q2. De plus, si la liste contient plusieurs éléments, alors comment puis-je déterminer l'index d'autres éléments car arraylist.indexof (item) renvoie l'index d'un premier élément à chaque fois?


2 commentaires

Est-ce que l'article remplace les équivalents et le hashcode? Ils ont besoin de.


Pourquoi n'exprime pas la classe ArrayList pour ajouter les fonctionnalités supplémentaires dont vous avez besoin? C'est pourquoi le COO existe;) Q1 peut être facilement effectué en implémentant un compteur pour chaque élément unique de la liste et en incrémentant chaque fois qu'un élément déjà existant est ajouté.


6 Réponses :


5
votes

Ceci est facile à faire à la main. XXX PRE>

Gardez à l'esprit que si vous ne remplacez pas égale code> dans votre article code> Classe, cette méthode utilisera l'identité d'objet (comme il s'agit de la mise en œuvre de objet.equals.equals () code>). p>

EDIT STROND>: Concernant votre deuxième question ( S'il vous plaît essayez de limiter les messages à une question à une question, vous pouvez également le faire à la main également. P>

public List<Integer> indices(ArrayList<Item> items, Item itemToCheck) {
    ArrayList<Integer> ret = new ArrayList<Integer>();
    for (int i = 0; i < items.size(); i++) {
        if (items.get(i).equals(itemToCheck)) {
            ret.add(i);
        }
    }
    return ret;
}


6 commentaires

Existe-t-il une autre méthode plus efficace car ma liste contient des milliers d'articles et un élément particulier peut être dupliqué au plus 4 ou 5 fois. Je pense donc que cela ne vaut pas la peine de comparer ces milliers d'articles à trouver ces 4 ou 5 duplicats. S'il vous plaît ne me suggère pas d'utiliser définir car il y a une raison solide pour ne pas utiliser définie dans mon cas.


Pensez au fait que pour compter les articles dont vous aurez besoin de toute façon pour parcourir toute la liste, car vous devrez les vérifier tous pour connaître le compte exact.


Si vous voulez quelque chose qui a une complexité de temps inférieure, vous n'avez pas de chance - ne connaît rien du contenu de votre liste, vous devez vérifier toutes les positions. Une optimisation consiste à comparer le hashcode de votre élément au code de chaque élément de la liste, mais si elles sont égales, vous devez toujours vérifier l'égalité en utilisant Equals () Comme la fonction de votre hachage peut avoir des collisions. Si vous vérifiez uniquement l'identité d'objet, il n'est pas nécessaire de le faire car est égal à comparera les adresses de mémoire ou quelque chose de similaire.


S'il s'agit de quelque chose qui doit être fait fréquemment et que le temps nécessaire, c'est un drain de performance, qu'une simple liste est la mauvaise structure à utiliser. Selon ce que vous essayez de faire, vous pourriez peut-être modifier l'élément pour inclure un compte, puis sur Ajouter la recherche de l'élément et incrémenter le compte. Ou créer une autre structure pour tenir les comptes. Etc. Il n'y a pas de moyen magique de rechercher une liste plus rapidement qu'une traversée séquentielle.


@Yatendra Goel Java peut itérer une liste avec des milliers (et même des centaines de milliers) d'objets en moins d'une seconde.


Bien que la vieille question, mais je souhaite ajouter ici, si vous pouvez obtenir une liste d'éléments uniques, puis itérer la liste d'origine, vous pouvez obtenir une légère performance. Mais maintenant, cela est hors de portée.



24
votes

Vous pouvez utiliser collections classe: xxx

retourne le nombre d'éléments de la collection spécifiée égale à l'objet spécifié. Plus formellement, renvoie le nombre d'éléments e dans la collection de telle sorte que (O == null? E == null: o.equals (e))).

Si vous avez besoin de compter les occurrences d'une longue liste, je vous suggère d'utiliser un hashmap pour stocker les comptoirs et les mettre à jour pendant que vous insérez de nouveaux éléments dans la liste. Cela éviterait de calculer tout type de comptoirs .. Mais bien sûr, vous n'aurez pas d'indices. xxx

Un indice final: vous pouvez utiliser d'autres collections framework (comme Collections Apache ) et utilisez un sac Datagruducture décrit comme

Définit une collection qui compte le nombre de fois qu'un objet apparaît dans la collection.

Donc exactement ce dont vous avez besoin ..


4 commentaires

Wow ne connaissait jamais cette méthode. Javadoc a trouvé ici: Java.sun.com/javase/6/docs/api/java/util/...


Votre première méthode est plus adaptée à mon besoin. Mais il y a un problème. Si j'ai trouvé plus d'un article dans la liste, comment récupérer ces autres éléments de la liste?


S'ils sont égaux, pourquoi vous déranger les récupérer? Vous savez déjà ce qui est à l'intérieur! Ou existe-t-il des champs qui n'entrent pas votre égal comparaison? Ou cherchez-vous à faire plus que simplement récupérer, comme peut-être la suppression?


Voulez-vous dire compteurs.Containskey (Newel)



0
votes

Comme les autres répondants ont déjà dit, si vous vous engagez fermement à stocker vos articles dans une arrache -liste non ordonnée, les éléments de comptage suivront O (n) heure, où n est le nombre d'éléments de la liste. Ici à ce jour, nous donnons des conseils, mais nous ne faisons pas de magie!

Comme je viens de laisser tomber, si la liste est recherchée beaucoup plus que sa modification, cela pourrait être logique de le garder trié. Si votre liste est triée, vous pouvez trouver votre article dans O (journal N), ce qui est beaucoup plus rapide; et si vous avez un HashCode implémentation qui va bien avec votre égale , tous les éléments identiques seront juste à côté de l'autre.

Une autre possibilité serait de créer et de maintenir deux structures de données en parallèle. Vous pouvez utiliser un hashmap contenant vos éléments sous forme de touches et de leur compte comme des valeurs. Vous seriez obligé de mettre à jour cette deuxième structure à tout moment votre liste change, mais des recherches de comptage d'éléments seraient O (1).


0 commentaires

0
votes

Je pourrais avoir tort, mais il me semble que la structure de données que vous souhaitez réellement être un Multiiset (de Google-Collections / GUAVA ) plutôt que une liste . Il permet des multiples, contrairement à définir , mais ne se soucie pas de la commande. Étant donné que, il a un int comptage (élément d'objet) méthode qui fait exactement ce que vous voulez. Et comme ce n'est pas une liste et que des implémentations soient appuyées par un hashmap , obtenir le compte est considérablement plus efficace.


0 commentaires

0
votes

Merci pour votre toute belle suggestion. Mais ce code ci-dessous est vraiment très utile car nous n'avons pas de méthode de recherche avec la liste qui peut donner un certain nombre d'occurrence.

void insert(Item newEl) 
{ 
   if (counters.contains(newEl)) 
     counters.put(newEl, counters.get(newEl)+1); 
   else 
     counters.put(newEl, 1); 

   items.add(newEl); 
 } 


0 commentaires

0
votes

Je sais que c'est un ancien poste, mais depuis que je n'ai pas vu de solution de carte de hasch, j'ai décidé d'ajouter un pseudo code sur Hash-Carte pour toute personne qui en a besoin à l'avenir. En supposant que les types de données d'arraylist et flottent. xxx


0 commentaires