sans - supprimer les doublons d'une liste java



Comment supprimer les doublons d'une liste basée sur un objet Java personnalisé et non un type primitif? (5)

Créez un objet HashMap avec int comme type de clé et votre classe comme type de valeur. Puis parcourez la liste et insérez chaque élément sur la carte en utilisant:

mymap.put(source.year, source);

Ensuite, supprimez tous les éléments de la liste origianl et passez en revue la carte et insérez chaque élément dans la liste.

https://code.i-harness.com

Avant de poster cette question, j'ai trouvé quelque chose de similaire posté ici . Mais la réponse était basée sur une chaîne. Cependant, j'ai une situation différente ici. Je n'essaie pas de supprimer String mais un autre objet appelé AwardYearSource. Cette classe a un attribut int appelé year. Donc, je veux supprimer les doublons en fonction de l'année. Par exemple, si l'année 2010 est mentionnée plus d'une fois, je souhaite supprimer cet objet AwardYearSource. Comment puis je faire ça?


Assez simplement. Bien que quelque chose me dérange sur les versions de la carte (pas que je doute qu'ils fonctionnent, il semble juste exagéré, en quelque sorte - bien que cette version ne soit pas nécessairement mieux à cet égard).
La réponse est fonctionnelle et threadsafe (en supposant que AwardYearSource est immuable).

public static List<AwardYearSource> removeDuplicateYears(
                                          final Collection<AwardYearSource> awards) {
    final ArrayList<AwardYearSource> input = new ArrayList<AwardYearSource>(awards);
    // If there's only one element (or none), guaranteed unique.
    if (input.size() <= 1) {
        return input;
    }
    final HashSet<Integer> years = new HashSet<Integer>(input.size(), 1);
    final Iterator<AwardYearSource> iter = input.iterator();
    while(iter.hasNext()) {
        final AwardYearSource award = iter.next();
        final Integer year = award.getYear();
        if (years.contains(year)) {
            iter.remove();
        } else {
            years.add(year);
        }
    }
    return input;       

}

Si votre classe AwardYearSource remplace les méthodes égales et hashcode (Eclipse peut générer les deux), vous pouvez les ajouter à un ensemble. L'ensemble ne contiendra aucun doublon.

public class AwardYearSource
{
    private final int year;

    public AwardYearSource(int year)
    {
        this.year = year;
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + year;
        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        AwardYearSource other = (AwardYearSource) obj;
        if (year != other.year)
            return false;
        return true;
    }

    @Override
    public String toString()
    {
        return String.valueOf(year);
    }


    public static void main(String[] args)
    {
        Set<AwardYearSource> set = new HashSet<AwardYearSource>();
        set.add(new AwardYearSource(2000));
        set.add(new AwardYearSource(2000));
        set.add(new AwardYearSource(2000));
        set.add(new AwardYearSource(2000));

        System.out.println(set);
    }
}

La sortie est [2000]. Un seul article dans l'ensemble.


Une autre façon serait de surcharger hashCode() et equals(Object obj) pour votre objet. Puisqu'il a juste un champ que vous voulez utiliser pour déterminer l'égalité, c'est assez simple. Quelque chose comme:

public boolean equals(Object obj) {
  if (obj == null || !(obj instanceof AwardYearSource)) {
    return false;
  }
  return (this.year == ((AwardYearSource)obj).year);
}
public int hashCode() {
  return this.year;
}

Ensuite, vous pouvez simplement coller tous les objets dans un Set pour supprimer les doublons:

Set<AwardYearSource> set = new Set<AwardYearSource>();

set.add(new AwardYearSource(2011));
set.add(new AwardYearSource(2012));
set.add(new AwardYearSource(2011));

for (AwardYearSource aws : set) {
  System.out.println(aws.year);
}

Set<Integer> set = new HashSet<>();
list.removeIf(i -> set.contains(i.getYear()) ? true : !set.add(i.getYear()));

Cela devrait aider dans lequel, la duplication est décidée en fonction de certaines propriétés (ou combinaison de propriétés), année dans ce cas. J'espère que cela t'aides.





set