web-dev-qa-db-fra.com

Comment trier le nom avec l'âge en java

Je suis nouveau sur Java 8. Je veux juste trier par nom. Mais la condition est la suivante: s’il existe des noms en double, ils doivent être triés par âge.

Par exemple, ma contribution est

tarun  28
arun   29
varun  12
arun   22

et la sortie devrait être

arun   22
arun   29
tarun  28
varun  12

Mais je reçois quelque chose comme

varun  12
arun   22
tarun  28
arun   29

Cela signifie qu'il est trié uniquement par âge ou par nom.

C'est le code qui est implémenté:

Classe POJO:

class Person {

    String fname;

    int age;

    public Person() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public Person(String fname,  int age) {
        this.fname = fname;

        this.age = age;
    }

    @Override
    public String toString() {
        return fname  + age;
    }
}

Classe de test:

public class Test {

    public static void main(String[] args) {
        List<Person> persons = new ArrayList<>();
        persons.add(new Person("tarun", 28));
        persons.add(new Person("arun", 29));
        persons.add(new Person("varun", 12));
        persons.add(new Person("arun", 22));

        Collections.sort(persons, new Comparator<Person>() {

            @Override
            public int compare(Person t, Person t1) {
                return t.getAge() - t1.getAge();
            }
        });
        System.out.println(persons);

    }
}
7
pawan sharma

Actuellement, vous comparez a) un seul attribut et b) n’utilisez pas vraiment les nouvelles fonctionnalités de Java 8.

Avec Java 8, vous pouvez utiliser références de méthodes et des comparateurs chaînés, comme ceci:

Collections.sort(persons, Comparator.comparing(Person::getFname)
    .thenComparingInt(Person::getAge));

Cela comparera deux instances Person en premier par leur fname et - si cela est égal - par leur age (avec une légère optimisation à thenComparingInt pour éviter la boxe).

8
Marvin

Vous devez d'abord comparer les noms. Si les noms sont les mêmes, alors et seulement alors le résultat dépend de la comparaison de l'âge

public static void main(String[] args) {
    List<Person> persons = new ArrayList<>();
    persons.add(new Person("tarun", 28));
    persons.add(new Person("arun", 29));
    persons.add(new Person("varun", 12));
    persons.add(new Person("arun", 22));

    Collections.sort(persons, new Comparator<Person>() {

        public int compare(Person t, Person t1) {
            int comp = t.getFname().compareTo(t1.getFname());
            if (comp != 0) {    // names are different
                return comp;
            }
            return t.getAge() - t1.getAge();
        }
    });
    System.out.println(persons);

}}

si vous voulez passer d’ascendant à décroissant, il suffit de changer le signe. par exemple.

 return -comp;

ou échangez la personne

prénom

 int comp = t1.getFname().compareTo(t.getFname());

âge

 return t1.getAge() - t.getAge();
3
stefan bachert

Vous êtes sur le bon chemin, mais votre méthode compare est incomplète.

Étant donné que compare est appelé pour décider quel élément de chaque paire doit être placé avant l'autre, il doit inclure toute la logique de comparaison, pas seulement celle qui permet de départager. Votre code trie uniquement sur l'âge, ignorant complètement le nom.

La logique devrait aller comme ceci:

  • Comparez les noms en utilisant t.getFname().compareTo(t1.getFname())
  • Si les noms sont pas identiques, retourne le résultat de la comparaison
  • Sinon, renvoyez le résultat de la comparaison des âges.

La manière correcte de comparer des nombres entiers est d'utiliser la méthode statique Integer.compare , c'est-à-dire Integer.compare(t.getAge(), t1.getAge()).

3
dasblinkenlight

Votre Comparator ne fait que trier par âge et non par nom.

Vous pouvez l'essayer comme ça:

new Comparator<Person>() {
    @Override
    public int compare(Person t, Person t1) {
        int ret = t.getFname().compareTo(t1.getFname());
        if (ret == 0) {
           ret = Integer.compare(t.getAge(), t1.getAge()); 
        }
        return ret;
    }
}

Vous pouvez également penser à implémenter Comparable<Person> dans la classe Person elle-même:

class Person implements Comparable<Person> {
    @Override
    public int compareTo(Person p) {
        int ret = fname.compareTo(p.fname);
        if (ret == 0) {
           ret = Integer.compare(age, p.getAge()); 
        }
        return ret;

    }
}
1
Dorian Gray

Ceci est simple une ligne comparaison en utilisant l'opérateur ternaire pour trier les objets. Pas besoin d'écrire autant si/else block .

Collections.sort(persons, new Comparator<Person>() {

    @Override
    public int compare(Person t1, Person t2) {

        return t1.getFname().equals(t2.getFname()) ? t1.getAge()-t2.getAge() : t1.getFname().compareTo(t2.getFname());

    }
});
0
nagendra547

Vous pouvez utiliser la méthode Comparator.comparing , introduite dans Java 8, renvoie un objet Comparator qui utilisera le champ spécifié comme clé de tri. 

final Function<Person, Integer> byAge = person -> person.getAge();   
final Function<Person, String> byTheirName = person -> person.getFname();
System.out.println("Sorted in ascending order by age and name: ");
        List<Person> sortedlist =   people.stream()
            .sorted(Comparator.comparing(byAge).thenComparing(byTheirName))
            .collect(Collectors.toList());
        sortedlist.forEach(System.out::println);

Nous avons d’abord créé deux expressions lambda, l’une pour indiquer l’âge d’une personne donnée et l’autre pour renvoyer le nom de cette personne. Nous avons ensuite combiné ces deux expressions lambda dans l'appel de la méthode sorted() afin de comparer les deux propriétés. La méthode comparing() a créé et renvoyé un comparateur à comparer en fonction de l'âge. Sur le comparateur renvoyé, nous avons appelé la méthode thenComparing() pour créer une variable comparator comparée en fonction de l'âge et du nom.

0
Common Man