从Person类

时间:2017-10-12 05:20:30

标签: java object treeset

基本上,我要做的是为每个Person对象存储多个地址。我已决定通过将Address对象存储在Person类的TreeSet中来实现此目的。基本上我想将我创建的每个Address对象的toString()存储到我的TreeSet中。我通过Person类的addAddress()方法传递Address对象的属性,该方法将属性传递给Address类的构造函数。

我在指定的行上收到错误...

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");
   }
}

以下是错误消息:

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)

要明确:我不想将地址存储在一个字符串中,因为我希望以后能够单独操作每个属性。我也不希望地址类属性存储在Person类中,因为我需要多次迭代地址类才能为每个Person对象存储多个地址。

3 个答案:

答案 0 :(得分:2)

好吧,TreeSet要求对元素进行排序。您必须构造集合并为其提供一个比较器,该比较器知道如何对要添加的对象进行排序,或者对象本身需要知道如何相互比较。您可以使用Address实现Comparable,但为什么使用TreeSet?既然你的构造函数正在对super()进行不必要的(因为它是隐式的)调用,我想你是Java新手?也许你不需要TreeSet的排序功能,你可以使用HashSet(如果你只需要唯一性)。无论如何,如果您希望集合执行您期望的操作,则应覆盖hashcode()和equals()。如果你使用像Eclipse或IDEA这样的IDE,那么可能有一个代码模板来帮助解决这个问题。

答案 1 :(得分:2)

基本上你要做的是在TreeSet中存储一个对象。

Treeset是Sorted Collection,如果你在TreeSet中存储对象,那么Object应该实现Comparable,你应该提供一个基于对象应该排序的条件。

以下是代码: -

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());
    }
}

答案 2 :(得分:2)

问题是,要将某些内容放入TreeSet中,它们必须具有可比性。这是因为树集将尝试将您的项目排列在树结构中。如果不能抛出异常,那么放入树集的所有内容都必须实现Comparable

然而,地址无法进行逻辑比较,可以吗?你真的很难为地址编写compareTo方法。你如何确定一个地址是否比另一个地址“更大”?

因此,我认为TreeSet不是用于此目的的合适数据结构。我建议您改用HashSet。散列集要求您的项目实现hashCode,这是一个返回该对象唯一的数字的方法,equals。如果对象的哈希码相等,则两个对象在逻辑上也是相等的。

您可以使用Objects.hash来帮助您实现此目的:

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

或者,使用IDE生成的其中一个实现。这是我的IntelliJ IDEA得到的:

@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;
}

也应该实施equals方法。你可以这样做:

@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);

}