我有一个带有JList的Swing应用程序,它可以使用自定义列表模型。
模型有一个ArrayList来存储使用的对象。情况如下:
关闭应用程序后,listmodel中的所有对象都被序列化(以默认方式,类只实现Serializable
),并通过ObjectOutputStream
写入文件。应用程序启动时,将从文件中读取所有对象并再次存储在我的自定义ListModel
中。
我正在尝试添加一项功能,让用户也可以从他指定的文件中导入对象。另一个类中的静态方法从文件中读取所有对象,并在ArrayList
中返回它们。然后,我在MainForm
类中使用for-each循环来存储ArrayList
中返回的ListModel
中的每个对象。在循环中,我想检查ListModel
是否已经包含某个对象,但是这不起作用。
在代码中,我正在执行以下操作:
for(MyObject o: readObjects) {
if(!myListModel.contains(o)) //listmodel just calls contains() on its ArrayList
myListModel.addElement(o);
}
但是,即使对象已经在ArrayList中(我继续从同一个文件导入对象),它们仍然仍然添加。
问题是,反序列化时对象如何不再相等,是否有办法比较它们?
答案 0 :(得分:2)
这是一个简单的java对象
public class MyObject {
private String firstname;
private String lastname;
private String email;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstname == null) ? 0 : firstname.hashCode());
result = prime * result
+ ((lastname == null) ? 0 : lastname.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyObject other = (MyObject) obj;
if (firstname == null) {
if (other.firstname != null)
return false;
} else if (!firstname.equals(other.firstname))
return false;
if (lastname == null) {
if (other.lastname != null)
return false;
} else if (!lastname.equals(other.lastname))
return false;
return true;
}
}
(由eclipse生成的hashcode和equals)
如果你看一下equals()方法,你会看到在字段firstname和lastname上比较了2个对象,而且只有那些2.这意味着如果你在列表中插入这种类型的对象,你将能够使用contains(Object o)
并且如果对象包含相同的名字和姓氏,您将找到它。
答案 1 :(得分:1)
您需要覆盖对象的equals和hashcode方法(SO上提供了许多示例,例如here。
完成后,List的contains
方法将按预期运行。您的问题似乎与序列化无关。换句话说,以下代码:
List<MyObject> list = new ArrayList<MyObject>();
list.add(new MyObject());
System.out.println(list.contains(new MyObject()));
如果你不覆盖等于&amp;&gt; 将打印为false hashcode,如果你这样做,它可能会打印为true(取决于你的equals方法是否认为那些new MyObject()
是否等于)。您的IDE应该有办法为您自动生成代码。
如果您对contains
方法在对象上按预期工作感到满意,则序列化/反序列化应该按预期工作。