2017-09-03 5 views
0

J'ai besoin d'une carte triée où tous les éléments sont triés par une clé, mais je dois pouvoir obtenir des éléments par une autre clé.Est-il possible de forcer Map à trier d'une manière, mais obtenir des valeurs d'une autre manière?

Je suppose que je peux résoudre cette tâche en créant une clé personnalisée:

public class MyKey implements Comparable<MyKey>{ 
    private long id; 
    private double price; 

    public MyKey(long orderId, double price) { 
     this.id = id; 
     this.price = price; 
    } 

    @Override 
    public int hashCode(){ 
     return Objects.hash(id); 
    } 

    @Override 
    public boolean equals(Object o){ 
     if(!(o instanceof MyKey)) return false; 
     return id == ((MyKey) o).id; 
    } 

    @Override 
    public int compareTo(MyKey o) { 
     if(price > o.price) return 1; 
     if(price < o.price) return -1; 
     return 0; 
    } 
} 

Voici que je dois être en mesure d'obtenir des éléments par clé, mais je dois forcer carte être triées par prix.

J'ai essayé d'utiliser:

Map<MyKey, Integer> myTestMap = new ConcurrentSkipListMap<>(); 
myTestMap.put(new MyKey(1, 200.0), 1); 
myTestMap.put(new MyKey(2, 100.0), 2); 
myTestMap.put(new MyKey(3, 300.0), 3); 
myTestMap.put(new MyKey(6, 500.0), 6); 
myTestMap.put(new MyKey(5, 400.0), 5); 
myTestMap.put(new MyKey(4, 600.0), 4); 

cette carte de cas est triée avec succès par prix, mais je ne peux pas l'élément en utilisant:

System.out.println(myTestMap.get(new MyKey(2, 0))); 

Je dois fixer un prix aussi pour être en mesure d'obtenir l'élément:

System.out.println(myTestMap.get(new MyKey(2, 100.0))); 

Existe-t-il une solution de contournement dans ce cas?

+0

il semble que la solution la plus simple est – DPM

+0

@DPM, semble être la seule solution disponible pour le moment. Merci pour le conseil – Alexandr

+0

Vous pouvez également étendre ForwardingMap de la guava pour garder une trace de l'ordre de valeur en interne avec des valeurs étant une nouvelle classe de wrapper du prix et de l'objet. Je préfère réutiliser des composants mais cela ne nécessiterait pas beaucoup de codage. – DPM

Répondre

1

Pas de véritable solution à votre réponse, mais une explication pourquoi elle ne fonctionne pas: Si vous creusez dans ConcurrentSkipListMap, vous verrez que l'obtention d'un objet vérifie une structure-index interne et utilise la méthode compareTo de votre Comparable. Il ne s'agit pas seulement d'utiliser la méthode hashCode qui ne tient compte que de l'identifiant (pour lequel il semblerait plausible de ne donner que votre identifiant dans l'instance MyKey créée ad hoc). Je suggérerais aussi d'utiliser une approche différente. Pourquoi ne pas utiliser deux structures?