2017-10-12 11 views
2

Fondamentalement, ce que j'essaie de faire est de stocker plusieurs adresses pour chaque objet Person. J'ai décidé d'y parvenir en stockant des objets Address dans un TreeSet de la classe Person. Essentiellement je voudrais stocker le toString() de chaque objet d'adresse que je crée dans mon TreeSet. Je passe les propriétés d'un objet Address via la méthode addAddress() de la classe Person, qui transmet les propriétés au constructeur de la classe Address.Stockage de plusieurs objets Address dans un TreeSet à partir d'une classe Person

Je reçois une erreur sur la ligne spécifiée ...

public class Person { 
    private TreeSet<Address> addresses = new TreeSet<Address>(); 

    public void addAddress(String type, String street, String city, String state, String zip) { 
    //ERROR ON THIS LINE BELOW 
    Address addressObj = new Address(type, street, city, state, zip); 
    addresses.add(addressObj); 
    } 
} 

public class Address { 
    private String type; 
    private String street; 
    private String city; 
    private String state; 
    private String zip; 

    @Override 
    public String toString() { 
     return street + " " + city + " " + ", " + state + " " + zip + ": " + type; 
    } 

    public Address(String type, String street, String city, String state, String zip) { 
     super(); 
     this.type = type; 
     this.street = street; 
     this.city = city; 
     this.state = state; 
     this.zip = zip; 
    } 
} 


public class MainDriver { 

    public static void main(String[] args) { 
     Person p1 = new Person(); 
     p1.addAddress("Home", "321 Den Ave", "Orlando", "FL", "32792"); 
     p1.addAddress("Work", "4411 Alligator Court", "Orlando", "FL", "32792"); 
    } 
} 

Voici le message d'erreur:

Exception in thread "main" java.lang.ClassCastException: Address cannot be cast to java.lang.Comparable 
at java.util.TreeMap.compare(TreeMap.java:1294) 
at java.util.TreeMap.put(TreeMap.java:538) 
at java.util.TreeSet.add(TreeSet.java:255) 
at Person.addAddress(Person.java:64) 
at MainDriver.main(MainDriver.java:9) 

Pour être clair: Je ne veux pas stocker l'adresse dans une chaîne parce que je veux être capable de manipuler chaque propriété individuellement plus tard. Je ne souhaite pas non plus que les propriétés de classe d'adresses soient stockées dans la classe Personne car j'ai besoin de plusieurs itérations de la classe Address pour pouvoir stocker plusieurs adresses pour chaque objet Person.

Répondre

2

Le problème est, de mettre quelque chose dans un TreeSet, ils doivent être comparables. C'est parce qu'un ensemble d'arbres essayera d'organiser vos articles dans une structure en arbre. Si une exception ne peut pas être levée, tout ce que vous mettez dans un ensemble Tree doit implémenter Comparable.

Cependant, les adresses ne peuvent pas être comparées logiquement, peuvent-elles? Il est vraiment difficile pour vous d'écrire une méthode compareTo pour les adresses. Comment déterminez-vous si une adresse est "plus grande" qu'une autre?

Par conséquent, je pense que TreeSet n'est pas une structure de données appropriée à cet effet. Je vous suggère d'utiliser HashSet à la place. Les ensembles de hachage nécessitent que vos éléments implémentent hashCode, qui est une méthode qui renvoie un nombre unique à cet objet, et equals. Si les codes de hachage des objets sont égaux, les deux objets sont également logiquement égaux.

Vous pouvez utiliser Objects.hash pour vous aider à mettre en œuvre ceci:

@Override 
public int hashCode() { 
    return Objects,hash(type, street, city, state, zip); 
} 

Alternative, utilisez l'une des implémentations générées par votre IDE.Voici ce que mon IntelliJ IDEA a:

@Override 
public int hashCode() { 
    int result = type.hashCode(); 
    result = 31 * result + street.hashCode(); 
    result = 31 * result + city.hashCode(); 
    result = 31 * result + state.hashCode(); 
    result = 31 * result + zip.hashCode(); 
    return result; 
} 

La méthode equals devrait également être mis en œuvre aussi. Vous pouvez faire quelque chose comme:

@Override 
public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 

    Address address = (Address) o; 

    if (!type.equals(address.type)) return false; 
    if (!street.equals(address.street)) return false; 
    if (!city.equals(address.city)) return false; 
    if (!state.equals(address.state)) return false; 
    return zip.equals(address.zip); 

} 
2

Eh bien, TreeSet exige que les éléments soient triés. Soit vous devez construire l'ensemble et lui donner un comparateur qui sait comment trier les objets que vous ajoutez ou les objets eux-mêmes doivent savoir comment se comparer les uns aux autres. Vous pourriez avoir un outil d'adresse comparable, mais pourquoi utilisez-vous un TreeSet? Puisque votre constructeur fait l'appel inutile (parce que c'est implicite) à super(), je suppose que vous êtes nouveau à Java? Peut-être n'avez-vous pas besoin de la fonction de tri de TreeSet et vous pouvez vous débrouiller avec HashSet (si vous avez juste besoin de l'unicité). Quoi qu'il en soit, vous devez remplacer hashcode() et equals() si vous voulez que l'ensemble fasse ce que vous attendez. Si vous utilisez un EDI comme Eclipse ou IDEA, il y a probablement un modèle de code pour vous aider.

2

Fondamentalement, ce que vous essayez de faire est de stocker un objet dans TreeSet.

Treeset est trié Collection, si vous stockez l'objet dans TreeSet l'objet doit implémenter Comparable et vous devez fournir une condition sur quel objet de base doit être trié.

Voici le code: -

import java.util.Set; 
import java.util.TreeSet; 

class Person { 
    private Set<Address> addresses = new TreeSet<>(); 

    public void addAddress(String type, String street, String city, String state, String zip) { 
     //ERROR ON THIS LINE BELOW 
     Address addressObj = new Address(type, street, city, state, zip); 
     addresses.add(addressObj); 
    } 
} 

class Address implements Comparable{ 
    private String type; 
    private String street; 
    private String city; 
    private String state; 
    private String zip; 

    @Override 
    public String toString() { 
     return street + " " + city + " " + ", " + state + " " + zip + ": " + type; 
    } 

    public Address(String type, String street, String city, String state, String zip) { 
     super(); 
     this.type = type; 
     this.street = street; 
     this.city = city; 
     this.state = state; 
     this.zip = zip; 
    } 

    @Override 
    public int compareTo(Object o) { 
     Address address = (Address)o; 
     return this.type.compareTo(address.type); 
    } 
} 


public class MainDriver { 

    public static void main(String[] args) { 
     Person p1 = new Person(); 
     p1.addAddress("Home", "321 Den Ave", "Orlando", "FL", "32792"); 
     p1.addAddress("Work", "4411 Alligator Court", "Orlando", "FL", "32792"); 
     System.out.println(p1.toString()); 
    } 
}