0

我有一个带有 JList 的 Swing 应用程序,它与自定义列表模型一起使用。

该模型有一个 ArrayList 来存储使用的对象。情况如下:

关闭应用程序后,listmodel 中的所有对象都被序列化(默认情况下,该类只实现Serializable),并通过ObjectOutputStream. 当应用程序启动时,从文件中读取所有对象并ListModel再次存储在我的自定义中。

我正在尝试添加一项功能,让用户也可以从他指定的文件中导入对象。另一个类中的静态方法从文件中读取所有对象,并以ArrayList. 然后,我在我的MainForm类中使用 for-each 循环将每个对象从返回ArrayListListModel. 在循环中,我想检查是否ListModel已经包含某个对象,但这不起作用

在代码中,我正在执行以下操作:

for(MyObject o: readObjects) {
    if(!myListModel.contains(o)) //listmodel just calls contains() on its ArrayList
        myListModel.addElement(o);
}

但是,即使对象已经在 ArrayList 中(我一直从同一个文件中导入对象),它们仍然会被添加。

问题是,反序列化时为什么对象不再相等,有没有办法比较它们?

4

2 回答 2

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)和如果一个对象包含相同的名字和姓氏,你会找到它。

于 2012-04-17T15:43:18.977 回答
1

您需要覆盖对象的 equals 和 hashcode 方法(SO 上有许多示例,例如这里.

完成此操作后,containsList 的方法将按您预期的方式运行。您的问题似乎与序列化无关。换句话说,下面的代码:

List<MyObject> list = new ArrayList<MyObject>();
list.add(new MyObject());
System.out.println(list.contains(new MyObject()));

如果您不覆盖 equals & hashcode,将打印 false,而如果您这样做,它可能会打印 true(取决于您的 equals 方法是否认为这两个new MyObject()相等)。您的 IDE 应该有一种方法可以为您自动生成代码。

一旦您对该contains方法在您的对象上按预期工作感到满意,序列化/反序列化应该按预期工作。

于 2012-04-17T15:38:56.177 回答