2010-03-31 7 views
2

Je suis nouveau à Comparators en JavaComparator qui peut comparer LinkedHashMaps

Quelqu'un peut-il me aider à créer un Comparator pour comparer LinkedHashmaps en comparant les clés/valeurs?

+3

Pouvez-vous expliquer un peu plus? Donner un exemple d'une paire de LinkedHashMaps et pourquoi l'un serait considéré comme moins que l'autre? Notez qu'un comparateur de LinkedHashMaps est une chose extrêmement irrégulière à vouloir faire, même pour les experts. Se pourrait-il que vous vouliez simplement savoir s'ils sont égaux, pas ce qui est le plus grand? –

+0

** J'essaie de supprimer les entrées linkedhashmap en double d'une liste Voici le pseudo code ** 1. créer un Comparateur qui compare les HashMaps et les compare en comparant les paires clé/valeur qui vous intéressent. 2. utilisez Collections.sort (yourlist, yourcomparator); 3. Maintenant, toutes les cartes similaires les unes aux autres, en fonction de votre comparateur, sont adjacentes dans la liste. 4. Créez une nouvelle liste. 5. Parcourez votre première liste en gardant une trace de ce que vous avez vu en dernier. Si la valeur actuelle est différente de la dernière, ajoutez-la à votre nouvelle liste. La nouvelle liste ne doit contenir aucun doublon. – Gauranga

+0

http://stackoverflow.com/questions/2195455/remove-duplicates-from-list-of-hashmap-entries - Ceci est lié à la question au lien ci-dessus – Gauranga

Répondre

1

Voici un exemple de pseudo-code. Il ne gère pas les valeurs nulles (qui peuvent être ajoutées si vous le souhaitez) et compare Map et une carte ne sera pas très différente/difficile :). Il y a un cas de test et beaucoup de lignes gaspillées pour réellement mettre en place une liste de cartes, mais devrait être facile à suivre.

package com.ekanathk; 

import static org.junit.Assert.*; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.LinkedHashMap; 
import java.util.List; 
import java.util.Map; 

import org.junit.Test; 

class MapEntryComparator implements Comparator<Map<String, String>> { 

    private String[] keysToCompare; 

    //What are the key columns you want to compare ??? 
    public MapEntryComparator(String[] keysToCompare) { 
     this.keysToCompare = keysToCompare; 
    } 

    @Override 
    public int compare(Map<String, String> o1, Map<String, String> o2) { 
     for(String s: keysToCompare) { 
      //HANDLE NULLS if any 
      int comparison = o1.get(s).compareTo(o2.get(s)); 
      if(comparison != 0) { 
       return comparison; 
      } 
     } 
     return 0; 
    } 

} 
public class ComparatorCheck { 

    @Test 
    public void testSimple() { 
     LinkedHashMap<String, String> m1 = getMapSample("X", "M", "C", "D"); 
     LinkedHashMap<String, String> m2 = getMapSample("A", "B", "C", "D"); 
     LinkedHashMap<String, String> m3 = getMapSample("A", "B", "C", "D"); 
     LinkedHashMap<String, String> m4 = getMapSample("A", "B", "X", "D"); 

     List<LinkedHashMap<String, String>> list = new ArrayList<LinkedHashMap<String,String>>(); 
     list.add(m1); 
     list.add(m2); 
     list.add(m3); 
     list.add(m4); 

     MapEntryComparator comparator = new MapEntryComparator(new String[]{"k1", "k2", "k3"}); 

     Collections.sort(list, comparator); 

     assertEquals(m2, list.get(0)); 
     assertEquals(m3, list.get(1)); 
     assertEquals(m4, list.get(2)); 
     assertEquals(m1, list.get(3)); 
    } 

    private LinkedHashMap<String, String> getMapSample(String v1, String v2, String v3, String v4) { 
     LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(); 
     map.put("k1", v1); 
     map.put("k2", v2); 
     map.put("k3", v3); 
     map.put("k4", v4); 
     return map; 
    } 
} 
2

je ferais quelque chose comme ceci: (psuedocode)

for(each entry in firstList) { 
    a=firstList.nextKey(); 
    b=secondList.nextKey(); 
    if(a != b !! firstList.get(a) != firstList.get(b)) 
     return false; 
} 
return true; 

mais cela implique que vous utilisez l'identité de l'objet (en d'autres termes, chaque objet doit être le même objet exact dans les deux listes).

Si ce n'est pas le cas, vous devez implémenter equals dans chaque objet unique qui pourrait être soit dans la liste, puis remplacez:

if(a != b ... 

avec

if(!a.equals(b)... 

ou quelque chose comme ça . De plus, comme quelqu'un l'a dit dans les commentaires, il y a de très bonnes chances qu'il y ait une meilleure façon de résoudre tout problème que vous essayez de résoudre.

+0

c'est une solution plus simple que la mise en œuvre d'un comparateur (si vous avoir à comparer seulement dans un endroit de votre code).Cependant, je suppose que Java Standard Library n'a pas de comparateur d'égalité par défaut pour les mappages de hachage liés ...: /. +1 en passant – GameDeveloper

3

Chaque Map (en fait, toutes les sous-classes de AbstractMap) a déjà mis en œuvre la méthode equals(..) d'une manière qui compare les paires clé/valeur.

Ainsi, si vous utilisez un Comparator, vous pouvez utiliser:

public int compare(Map first, Map second){ 
     // appropriate null checks here 
     return first.equals(second) ? 0 : 1; 
} 

Mais je préfère mettre les Map s dans une nouvelle HashSet, qui supprime automatiquement les doublons:

Set<Map> uniqueMaps = new HashSet<Map>(listOfMaps); 
+0

Ceci n'est pas vrai, si vous avez 2 mappages de hachage liés avec les mêmes éléments (entrées clé/valeur) mais dans un ordre différent, 'equals' retournera vrai alors que les éléments de comparaison devraient retourner false. – GameDeveloper

+0

Je viens de tester avec deux LinkedHashMap avec les mêmes éléments mais dans un ordre différent et le 'equals' retourné faux. – Ithar