基本上,我要做的是为每个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对象存储多个地址。
答案 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);
}