375 votes

Java - Comment créer une nouvelle entrée (clé, valeur)

Je voudrais créer un nouvel élément qui ressemble à Util.Map.Entry qui contiendra la structure key, value.

Le problème est que je ne peux pas instancier un Map.Entry car c'est une interface.

Est-ce que quelqu'un sait comment créer un nouvel objet clé/valeur générique pour Map.Entry?

938voto

polygenelubricants Points 136838

Il existe public static class AbstractMap.SimpleEntry. Ne laissez pas la partie Abstract du nom vous tromper: ce n'est en fait PAS une classe abstraite (mais son AbstractMap de niveau supérieur l'est).

Le fait que ce soit une classe imbriquée static signifie que vous n'avez PAS besoin d'une instance AbstractMap englobante pour l'instancier, donc quelque chose comme ceci compile bien:

Map.Entry entry = new AbstractMap.SimpleEntry("exmpleString", 42);

Comme indiqué dans une autre réponse, Guava a également une méthode de fabrique static pratique Maps.immutableEntry que vous pouvez utiliser.


Vous avez dit:

Je ne peux pas utiliser Map.Entry lui-même car apparemment c'est un objet en lecture seule que je ne peux pas instancier avec instanceof

Ce n'est pas tout à fait exact. La raison pour laquelle vous ne pouvez pas l'instancier directement (c'est-à-dire avec new) est parce qu'il s'agit d'une interface Map.Entry.


Mise en garde et astuce

Comme indiqué dans la documentation, AbstractMap.SimpleEntry est @since 1.6, donc si vous êtes limité à 5.0, alors il n'est pas disponible pour vous.

Pour rechercher une autre classe connue qui implémente Map.Entry, vous pouvez effectivement consulter directement la javadoc. Depuis la version Java 6

Interface Map.Entry

Toutes les classes implémentant connues:

Malheureusement, la version 1.5 ne répertorie aucune classe implémentante connue que vous pouvez utiliser, alors vous devez peut-être vous contenter de implémenter votre propre classe.

0 votes

La ligne ci-dessus me renvoie une erreur de compilation (j'utilise Java 5, au fait) - le message d'erreur est : 'Le type AbstractMap.SimpleEntry n'est pas visible'

7 votes

Cela s'explique parce que AbstractMap.SimpleEntry n'était pas public jusqu'à Java 6, comme vous pouvez le voir dans la documentation.

0 votes

D'accord, donc pour résumer la courte discussion - il n'y a pas de solution prête à l'emploi en Java 5 - je devrais utiliser ma propre implémentation pour cela.

84voto

Jesper Points 65733

Vous pouvez simplement implémenter vous-même l'interface Map.Entry:

import java.util.Map;

final class MyEntry implements Map.Entry {
    private final K key;
    private V value;

    public MyEntry(K key, V value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public K getKey() {
        return key;
    }

    @Override
    public V getValue() {
        return value;
    }

    @Override
    public V setValue(V value) {
        V old = this.value;
        this.value = value;
        return old;
    }
}

Et ensuite l'utiliser:

Map.Entry entry = new MyEntry("Hello", 123);
System.out.println(entry.getKey());
System.out.println(entry.getValue());

1 votes

Pouvez-vous s'il vous plaît expliquer pourquoi certaines implémentations de Map ont une clé finale (comme dans HashMap, ConcurrentHashMap), mais pas dans d'autres implémentations comme TreeMap, WeakHashMap?

12 votes

Le code fourni n'est pas entièrement correct car il ne remplace pas les méthodes equals et hashCode, ce qui est requis par l'interface Map.Entry

0 votes

À partir de Java 7 Update 80, j'ai implémenté ce qui précède et cela a fonctionné (pastebin). Aucune autre méthode n'a été remplacée.

56voto

finnw Points 24592

Essayez Maps.immutableEntry de Guava

Cela présente l'avantage d'être compatible avec Java 5 (contrairement à AbstractMap.SimpleEntry qui nécessite Java 6.)

13voto

tanghao Points 71

Pourquoi Map.Entry? Je suppose qu'un couple clé-valeur convient pour ce cas.

Utiliser java.util.AbstractMap.SimpleImmutableEntry ou java.util.AbstractMap.SimpleEntry

4voto

Nels Beckman Points 9949

J'ai défini une classe générique Pair que j'utilise tout le temps. C'est génial. En prime, en définissant une méthode de fabrique statique (Pair.create) je n'ai à écrire les arguments de type qu'à moitié aussi souvent.

public class Pair {

    private A component1;
    private B component2;

    public Pair() {
            super();
    }

    public Pair(A component1, B component2) {
            this.component1 = component1;
            this.component2 = component2;
    }

    public A fst() {
            return component1;
    }

    public void setComponent1(A component1) {
            this.component1 = component1;
    }

    public B snd() {
            return component2;
    }

    public void setComponent2(B component2) {
            this.component2 = component2;
    }

    @Override
    public String toString() {
            return "<" + component1 + "," + component2 + ">";
    }

    @Override
    public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result
                            + ((component1 == null) ? 0 : component1.hashCode());
            result = prime * result
                            + ((component2 == null) ? 0 : component2.hashCode());
            return result;
    }

    @Override
    public boolean equals(Object obj) {
            if (this == obj)
                    return true;
            if (obj == null)
                    return false;
            if (getClass() != obj.getClass())
                    return false;
            final Pair other = (Pair) obj;
            if (component1 == null) {
                    if (other.component1 != null)
                            return false;
            } else if (!component1.equals(other.component1))
                    return false;
            if (component2 == null) {
                    if (other.component2 != null)
                            return false;
            } else if (!component2.equals(other.component2))
                    return false;
            return true;
    }

    public static  Pair create(A component1, B component2) {
            return new Pair(component1, component2);
    }

}

1 votes

Désolé, j'ai posté ceci avant de lire tous les autres commentaires. Il semble que vous vouliez quelque chose qui est inclus dans la bibliothèque standard...

3 votes

Google Guava souligne à juste titre que les implémentations de Pair sont une mauvaise chose. Source

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X