web-dev-qa-db-fra.com

Accéder à la dernière entrée d'une carte

Comment déplacer une entrée HashMap particulière vers la dernière position?

Par exemple, j'ai des valeurs HashMap comme ceci:

HashMap<String,Integer> map = new HashMap<String,Integer>();

map= {Not-Specified 1, test 2, testtest 3};

"Non spécifié" peut venir dans n'importe quelle position. il peut venir en premier ou au milieu de la carte. Mais je veux déplacer le "Non spécifié" à la dernière position.

Comment puis je faire ça? Merci d'avance.

52
Gnaniyar Zubair

Pour répondre à votre question en une phrase:

Par défaut, Maps n'a pas de dernière entrée, cela ne fait pas partie de leur contrat.


Et une remarque: c'est une bonne pratique de coder contre des interfaces, pas les classes d'implémentation (voir Effective Java par Joshua Bloch , Chapter 8, Item 52: Se référer aux objets par leurs interfaces ).

Votre déclaration devrait donc se lire:

Map<String,Integer> map = new HashMap<String,Integer>();

(Toutes les cartes partagent un contrat commun, le client n'a donc pas besoin de savoir de quel type de carte il s'agit, sauf s'il spécifie une sous-interface avec un contrat étendu).


Solutions possibles

Cartes triées:

Il y a une sous-interface SortedMap qui étend l'interface de la carte avec des méthodes de recherche par ordre et elle a une sous-interface NavigableMap qui étend encore plus loin. L'implémentation standard de cette interface, TreeMap , vous permet de trier les entrées soit par ordre naturel (si elles implémentent l'interface Comparable ) ou par un Comparator fourni.

Vous pouvez accéder à la dernière entrée via la méthode lastEntry :

NavigableMap<String,Integer> map = new TreeMap<String, Integer>();
// add some entries
Entry<String, Integer> lastEntry = map.lastEntry();

Cartes liées:

Il existe également le cas particulier de LinkedHashMap , une implémentation HashMap qui stocke l'ordre dans lequel les clés sont insérées. Il n'y a cependant pas d'interface pour sauvegarder cette fonctionnalité, ni de moyen direct d'accéder à la dernière clé. Vous ne pouvez le faire que par des astuces telles que l'utilisation d'une liste entre les deux:

Map<String,String> map = new LinkedHashMap<String, Integer>();
// add some entries
List<Entry<String,Integer>> entryList =
    new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
Entry<String, Integer> lastEntry =
    entryList.get(entryList.size()-1);

Solution appropriée:

Puisque vous ne contrôlez pas l'ordre d'insertion, vous devez utiliser l'interface NavigableMap, c'est-à-dire que vous écririez un comparateur qui positionne le Not-Specified dernière entrée.

Voici un exemple:

final NavigableMap<String,Integer> map = 
        new TreeMap<String, Integer>(new Comparator<String>() {
    public int compare(final String o1, final String o2) {
        int result;
        if("Not-Specified".equals(o1)) {
            result=1;
        } else if("Not-Specified".equals(o2)) {
            result=-1;
        } else {
            result =o1.compareTo(o2);
        }
        return result;
    }

});
map.put("test", Integer.valueOf(2));
map.put("Not-Specified", Integer.valueOf(1));
map.put("testtest", Integer.valueOf(3));
final Entry<String, Integer> lastEntry = map.lastEntry();
System.out.println("Last key: "+lastEntry.getKey()
         + ", last value: "+lastEntry.getValue());

Sortie:

Dernière clé: non spécifiée, dernière valeur: 1

Solution utilisant HashMap:

Si vous devez vous fier à HashMaps, il existe toujours une solution, en utilisant a) une version modifiée du comparateur ci-dessus, b) un List initialisé avec le Map entrySet et c) la méthode d'assistance Collections.sort () :

    final Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("test", Integer.valueOf(2));
    map.put("Not-Specified", Integer.valueOf(1));
    map.put("testtest", Integer.valueOf(3));

    final List<Entry<String, Integer>> entries =
        new ArrayList<Entry<String, Integer>>(map.entrySet());
    Collections.sort(entries, new Comparator<Entry<String, Integer>>(){

        public int compareKeys(final String o1, final String o2){
            int result;
            if("Not-Specified".equals(o1)){
                result = 1;
            } else if("Not-Specified".equals(o2)){
                result = -1;
            } else{
                result = o1.compareTo(o2);
            }
            return result;
        }

        @Override
        public int compare(final Entry<String, Integer> o1,
            final Entry<String, Integer> o2){
            return this.compareKeys(o1.getKey(), o2.getKey());
        }

    });

    final Entry<String, Integer> lastEntry =
        entries.get(entries.size() - 1);
    System.out.println("Last key: " + lastEntry.getKey() + ", last value: "
        + lastEntry.getValue());

}

Sortie:

Dernière clé: non spécifiée, dernière valeur: 1

145
Sean Patrick Floyd

HashMap n'a pas "la dernière position", car il n'est pas trié.

Vous pouvez utiliser d'autres Map qui implémentent Java.util.SortedMap, le plus populaire est TreeMap.

17

Un SortedMap est le meilleur choix logique, mais une autre option consiste à utiliser un LinkedHashMap qui conserve deux modes de commande, le dernier ajouté en dernier et le dernier accédé en dernier. Voir les Javadocs pour plus de détails.

5
Peter Lawrey

déplacer n'a pas de sens pour une table de hachage, car c'est un dictionnaire avec un code de hachage pour le regroupement basé sur la clé, puis une liste liée pour entrer en collision les codes de hachage résolus via égaux. Utilisez un TreeMap pour les cartes triées, puis passez un comparateur personnalisé.

1
anand

Dans un tel scénario, la dernière clé utilisée est généralement connue, elle peut donc être utilisée pour accéder à la dernière valeur (insérée avec celle):

class PostIndexData {
    String _office_name;
    Boolean _isGov;
    public PostIndexData(String name, Boolean gov) {
        _office_name = name;
        _isGov = gov;
    }
}
//-----------------------
class KgpData {
    String _postIndex;
    PostIndexData _postIndexData;
    public KgpData(String postIndex, PostIndexData postIndexData) {
        _postIndex = postIndex;
        _postIndexData = postIndexData;;
    }
}

public class Office2ASMPro {
    private HashMap<String,PostIndexData> _postIndexMap = new HashMap<>();
    private HashMap<String,KgpData> _kgpMap = new HashMap<>();
...
private void addOffice(String kgp, String postIndex, String officeName, Boolean gov) {
            if (_postIndexMap.get(postIndex) == null) {
                _postIndexMap.put(postIndex, new PostIndexData(officeName, gov));
            }
            _kgpMap.put( kgp, new KgpData(postIndex, _postIndexMap.get(postIndex)) );
        }
0
Mad Calm

Lorsque vous utilisez des nombres comme clé, je suppose que vous pouvez également essayer ceci:

        Map<Long, String> map = new HashMap<>();
        map.put(4L, "The First");
        map.put(6L, "The Second");
        map.put(11L, "The Last");

        long lastKey = 0;
        //you entered Map<Long, String> entry
        for (Map.Entry<Long, String> entry : map.entrySet()) {
            lastKey = entry.getKey();
        }
        System.out.println(lastKey); // 11
0
Yoshua Nahar
Find missing all elements from array
        int[] array = {3,5,7,8,2,1,32,5,7,9,30,5};
        TreeMap<Integer, Integer> map = new TreeMap<>();
        for(int i=0;i<array.length;i++) {
            map.put(array[i], 1);
        }
        int maxSize = map.lastKey();
        for(int j=0;j<maxSize;j++) {
            if(null == map.get(j))
                System.out.println("Missing `enter code here`No:"+j);
        }
0
Muruganandam C