web-dev-qa-db-fra.com

Comment écrire une méthode compareTo qui compare des objets?

J'apprends à propos des tableaux et, fondamentalement, j'ai un tableau qui regroupe un nom, un prénom et un score.

Je dois écrire une méthode compareTo qui comparera le nom de famille puis le prénom afin que la liste puisse être triée par ordre alphabétique en commençant par les noms de famille. Si deux personnes portent le même nom de famille, elles trieront le prénom.

Je suis confus, car toutes les informations de mon livre comparent des nombres, pas des objets et des chaînes.

Voici ce que j'ai codé jusqu'à présent. Je sais que c'est faux, mais cela explique au moins ce que je pense faire:

public int compare(Object obj) // creating a method to compare 
{   
    Student s = (Student) obj; // creating a student object

    // I guess here I'm telling it to compare the last names?
    int studentCompare = this.lastName.compareTo(s.getLastName()); 

    if (studentCompare != 0)
        return studentCompare;
    else 
    {
        if (this.getLastName() < s.getLastName())
            return - 1;

        if (this.getLastName() > s.getLastName())
            return 1;
    }
    return 0;
}

Je sais que les symboles < et > sont incorrects, mais comme je l'ai dit, mon livre ne vous montre que comment utiliser la variable compareTo.

28
Jeremy B

C'est la bonne façon de comparer les chaînes:

int studentCompare = this.lastName.compareTo(s.getLastName()); 

Cela ne compilera même pas:

if (this.getLastName() < s.getLastName())

Utilisation if (this.getLastName().compareTo(s.getLastName()) < 0) à la place.

Donc, pour comparer l'ordre poing/nom de famille dont vous avez besoin:

int d = getFirstName().compareTo(s.getFirstName());
if (d == 0)
    d = getLastName().compareTo(s.getLastName());
return d;
24
Eugene Retunsky

La méthode compareTo est décrite comme suit:

Compare cet objet avec l'objet spécifié pour la commande. Retourne un entier négatif, zéro ou entier positif car cet objet est inférieur à supérieur, égal ou supérieur à l'objet spécifié.

Disons que nous aimerions comparer les Jedis par leur âge:

class Jedi implements Comparable<Jedi> {

    private final String name;
    private final int age;
        //...
}

Ensuite, si notre Jedi est plus âgé que celui fourni, vous devez retourner un résultat positif, s’ils ont le même âge, vous revenez à 0, et si notre Jedi est plus jeune, vous renvoyez un résultat négatif.

public int compareTo(Jedi jedi){
    return this.age > jedi.age ? 1 : this.age < jedi.age ? -1 : 0;
}

En implémentant la méthode compareTo (provenant de l'interface Comparable), vous définissez ce que l'on appelle un ordre naturel . Toutes les méthodes de tri dans JDK utiliseront cet ordre par défaut .

Il existe des occasions dans lesquelles vous voudrez peut-être baser votre comparaison sur d'autres objets et non sur un type primitif. Par exemple, copare Jedis en fonction de leurs noms. Dans ce cas, si les objets comparés implémentent déjà Comparable, vous pouvez effectuer la comparaison à l'aide de sa méthode compareTo.

public int compareTo(Jedi jedi){
    return this.name.compareTo(jedi.getName());
}

Ce serait plus simple dans ce cas.

Maintenant, si vous souhaitez utiliser à la fois le nom et l’âge comme critère de comparaison, vous devez décider de votre choix de comparaison, ce qui a la priorité. Par exemple, si deux Jedis portent le même nom, vous pouvez utiliser leur âge pour décider lequel va le premier et lequel va le second.

public int compareTo(Jedi jedi){
    int result = this.name.compareTo(jedi.getName());
    if(result == 0){
        result = this.age > jedi.age ? 1 : this.age < jedi.age ? -1 : 0;
    }
    return result;
}

Si vous aviez un tableau de Jedis

Jedi[] jediAcademy = {new Jedi("Obiwan",80), new Jedi("Anakin", 30), ..}

Tout ce que vous avez à faire est de demander à la classe Java.util.Arrays d'utiliser sa méthode de tri.

Arrays.sort(jediAcademy);

Cette méthode Arrays.sort utilisera votre méthode compareTo pour trier les objets un par un.

18
Edwin Dalorzo

if (s.compareTo(t) > 0) va comparer la chaîne s à la chaîne t et renvoyer la valeur int souhaitée.

    public int Compare(Object obj) // creating a method to compare {   
        Student s = (Student) obj; //creating a student object

        // compare last names
        return  this.lastName.compareTo(s.getLastName());    
    }

Maintenant, testez simplement le rendement négatif de la méthode comme vous le feriez normalement.

À votre santé

1
RyanS

Vous êtes presque tout le chemin.

Vos premières lignes, comparant le nom de famille, sont sur la bonne voie. La méthode compareTo () sur chaîne renverra un nombre négatif pour une chaîne dans l'ordre alphabétique avant et un nombre positif pour un dans l'ordre alphabétique après.

Maintenant, il vous suffit de faire la même chose pour votre prénom et votre score. 

En d’autres termes, si Nom 1 == Nom 2, cochez ensuite votre prénom. Si le prénom est le même, vérifiez votre score ensuite. (Pensez à imbriquer vos blocs if/then.)

1
Jonathan B

Pensez à utiliser l'interface Comparator décrite ici qui utilise des génériques afin d'éviter de transtyper Object en Student

Comme Eugene Retunsky l'a dit, votre première partie est la bonne façon de comparer Strings. De même, si les lastNames sont égaux, je pense que vous vouliez comparer firstNames, auquel cas il suffit d'utiliser compareTo de la même manière.

1
darrengorman

Si vous utilisez la méthode compare To de l’interface Comparable dans n’importe quelle classe, vous pouvez utiliser cette fonction pour organiser la chaîne de manière lexicographique.

public class Student() implements Comparable<Student>{

public int compareTo(Object obj){
if(this==obj){
    return 0;
}
if(obj!=null){
    String objName = ((Student)obj).getName();
    return this.name.comapreTo.(objName);
}
}
0
VISHAL SINGH

Je n'aurais pas de paramètre de type d'objet, inutile de le transmettre à Student si nous savons qu'il sera toujours de type Student.

En ce qui concerne l'explication, "result == 0" ne se produira que lorsque les noms de famille sont identiques. À ce stade, nous comparons les prénoms et renvoyons cette valeur.

public int Compare(Object obj)
{       
    Student student = (Student) obj;
    int result = this.getLastName().compareTo( student.getLastName() );

    if ( result == 0 )
    {
        result = this.getFirstName().compareTo( student.getFirstName() );
    }

    return result;
}
0
Jonathan Payne

Une chaîne est un objet en Java.

tu pourrais comparer comme ça,

if(this.lastName.compareTo(s.getLastName() == 0)//last names are the same
0
ChadNC