3
votes

Trier une carte d'abord par valeur puis par clé

Je suis en fait capable de trier ma carte uniquement sur la base de la clé et de la valeur , j'ai même essayé de les trier comme ci-dessous :

J'ai trié les étudiants en fonction du pays, et s'il se trouve que deux étudiants ont les mêmes états , triez par StudentID uniquement parmi les pays correspondants. p >

Ce que j'ai essayé jusqu'à présent:

  26=Malmo
  14=Orebro
  110=Orebro
  146=Sweden
  148=Sweden

Le résultat que j'obtiens ** (résultat réel) **

14=Orebro
26=Malmo
110=Orebro
146=Sweden
148=Sweden


5 commentaires

S'il n'est pas nécessaire de stocker les entrées triées, le comparateur personnalisé devrait suffire


@CaseyRule Je ne crois pas que ce soit un doublon, car l'OP veut trier par valeur puis par clé.


@JacobG. J'avais en fait identifié stackoverflow.com/questions/3074154/... comme dupliquant cette question, mais cette question a été signalée comme un doublon de stackoverflow.com/questions/109383/... . Il semble que la propriété transitive de duplication ne soit pas tenue dans ce cas :)


@CaseyRule Ah, c'est drôle; bonne prise!


votre problème est résolu ou non ??


4 Réponses :


3
votes

Remarque: vos sorties attendues et réelles ne correspondent pas aux clés que vous avez ajoutées à votre Map.


La raison pour laquelle votre code ne fonctionne pas est que vous vous appelez Stream # sorted deux fois avec deux Comparator s séparés, donc le premier appel à Stream # sorted est inutile dans votre cas (car il est remplacé par le deuxième appel).


J'ai pu obtenir la sortie attendue en passant un comparateur personnalisé à Stream # sorted :

6=Malmo
26=Malmo
14=Orebro
110=Orebro
146=Sweden
148=Sweden

Sortie:

Map.Entry.<Integer, String>comparingByValue()
    .thenComparing(Map.Entry.comparingByKey())


0 commentaires

1
votes

Il y a quelque temps, j'ai répondu à Comment trier le nom avec l'âge en java , De nombreuses similitudes avec votre question en dehors de la structure de données utilisée pour le stockage. Traverser chaque clé et la trier, puis à nouveau en valeur, puis la trier est assez fastidieuse et peut vous rendre très confus. rappelez-vous simplement comment vous aviez l'habitude de parcourir dans Map lorsque vous n'utilisiez pas Stream :

6=Malmo
26=Malmo
14=Orebro
110=Orebro
146=Sweden
148=Sweden

studentMaster.entrySet().stream()
    .sorted(Comparator.comparing((Map.Entry<Integer, String> m) -> m.getValue())
              .thenComparing(Map.Entry::getKey)).forEach(System.out::println);

Sortie

for (Map.Entry<String,String> entry : somemap.entrySet()){..Some Statements..};


0 commentaires

0
votes

Le Comparator devrait ressembler à ceci:

6=Malmo
26=Malmo
14=Orebro
110=Orebro
146=Sweden
148=Sweden

Et puis le transmettre à la méthode Stream # sorted : studentMaster .entrySet (). stream (). sorted (comparateur) .forEach (System.out :: println);

Sortie:

Comparator<Entry<Integer, String>> comparator = (o1, o2) -> {
    int i = o1.getValue().compareTo(o2.getValue());
    if (i == 0) {
        return o1.getKey().compareTo(o2.getKey());
    } else {
        return i;
    }
};


0 commentaires

0
votes

2 façons:

  • Utilisez TreeSet avec Comparable pojo.
  • Utilisez TreeSet avec un comparateur personnalisé.
  • code> Comparable pojo.)
id = 6, master = Malmo
id = 26, master = Malmo
id = 14, master = Orebro
id = 110, master = Orebro
id = 146, master = Sweden
id = 148, master = Sweden

TmpComparator.java

( Utilisez TreeSet avec un Comparator personnalisé .)

import java.util.*;

public class TmpComparator {
    static Comparator<StudentMaster> smc = new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
            StudentMaster sm1 = (StudentMaster) o1, sm2 = (StudentMaster) o2;

            int masterFlag = sm1.master.compareTo(sm2.master);
            return (masterFlag == 0) ? sm1.id.compareTo(sm2.id) : masterFlag;
        }
    };

    static class StudentMaster {
        private Integer id;
        private String master;

        public StudentMaster(Integer id, String master) {
            this.id = id;
            this.master = master;
        }

        @Override
        public boolean equals(Object o) {
            StudentMaster osm = (StudentMaster) o;
            return id == osm.id && master.equals(osm.master);
        }

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

        public String toString() {
            StringBuilder sb = new StringBuilder();
            Formatter fm = new Formatter(sb);

            fm.format("id = %d, master = %s\n", id, master);

            fm.close();
            return sb.toString();
        }
    }

    public static void test() {
        final Set<StudentMaster> smSet = new TreeSet<>(smc);

        smSet.add(new StudentMaster(146, "Sweden"));
        smSet.add(new StudentMaster(148, "Sweden"));
        smSet.add(new StudentMaster(110, "Orebro"));
        smSet.add(new StudentMaster(6, "Malmo"));
        smSet.add(new StudentMaster(14, "Orebro"));
        smSet.add(new StudentMaster(26, "Malmo"));

        for (StudentMaster sm : smSet) {
            System.out.print(sm);
        }
    }

    public static void main(String[] args) {
        test();
    }
}

Exécutez simplement le main () .

Les résultats des deux sont identiques:

import java.util.*;

public class Tmp {
    static class StudentMaster implements Comparable<StudentMaster> {
        private Integer id;
        private String master;

        public StudentMaster(Integer id, String master) {
            this.id = id;
            this.master = master;
        }

        @Override
        public int compareTo(StudentMaster other) {
            int masterFlag = master.compareTo(other.master);
            return (masterFlag == 0) ? id.compareTo(other.id) : masterFlag;
        }

        @Override
        public boolean equals(Object o) {
            StudentMaster osm = (StudentMaster) o;
            return id == osm.id && master.equals(osm.master);
        }

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

        public String toString() {
            StringBuilder sb = new StringBuilder();
            Formatter fm = new Formatter(sb);

            fm.format("id = %d, master = %s\n", id, master);

            fm.close();
            return sb.toString();
        }
    }

    public static void test() {
        final Set<StudentMaster> smSet = new TreeSet<>();

        smSet.add(new StudentMaster(146, "Sweden"));
        smSet.add(new StudentMaster(148, "Sweden"));
        smSet.add(new StudentMaster(110, "Orebro"));
        smSet.add(new StudentMaster(6, "Malmo"));
        smSet.add(new StudentMaster(14, "Orebro"));
        smSet.add(new StudentMaster(26, "Malmo"));

        for (StudentMaster sm : smSet) {
            System.out.print(sm);
        }
    }

    public static void main(String[] args) {
        test();
    }
}

Astuces

  • Dans le code de production, le equals () doit être amélioré, il s'agit d'une version simplifiée pour le test uniquement.


0 commentaires