[英]equals and hasCode are not working as expected
编辑 /已解决仍在寻找更好的答案我在这里有答案如何从ArrayList中删除重复的元素? 它正在工作,我的问题是与仅列表而不是集合有关。 由于已经实现了整个应用程序流程列表,因此我很难将所有列表引用更改为“设置引用”,因为https://docs.oracle.com/javase/7/docs/api/java/util/List.html具有get(..)Set没有get(..)。
每个添加的对象都是一个新的实例。 嗨,我有一个模特班
public final class MyClass implements Comparable<MyClass> {
public static final int APP = 0;
public static final int FILE = 1;
public static final int FOLDER = 2;
private String name;
private String path;
private String pkg;
private Long size;
private boolean selected;
private Integer type;
public MyClass(String name, String path, String pkg, Long size, boolean selected, int type) {
this.name = name;
this.path = path;
this.pkg = pkg;
this.size = size;
this.selected = selected;
this.type = type;
if (!TextUtils.isEmpty(path)) {
File file = new File(path);
if (file.exists()) {
this.size = file.length();
}
}
}
public String getName() {
return name;
}
public String getPath() {
return path;
}
public String getSize() {
return FileUtils.getReadableFileSize(size);
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public Integer getType() {
return type;
}
public String getPkg() {
return pkg;
}
@Override
public String toString() {
return "{Pkg=" + pkg + ", Path=" + path + ", size=" + size + ", hashcode: " + hashCode() +"}";
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
MyClass myclass = (MyClass) o;
if (path != null ? !path.equals(myclass.path) : myclass.path != null)
return false;
if (pkg != null ? !pkg.equals(myclass.pkg) : myclass.pkg != null)
return false;
return size != null ? size.equals(myclass.size) : myclass.size == null;
}
@Override
public int hashCode() {
int result = path != null ? path.hashCode() : 0;
result = 31 * result + (pkg != null ? pkg.hashCode() : 0);
result = 31 * result + (size != null ? size.hashCode() : 0);
return result;
}
@Override
public int compareTo(MyClass myclass) {
return myclass.getType().compareTo(this.type);
}
}
但是,当我创建公共对象时,这些对象将被添加到列表中,即使它们的哈希码相同,它在列表中也是重复的。 我在这里可能做错了任何事情。
List的toString的输出如下:
[{
Pkg = com.a.bc,
Path = /data/app / com.a.bc - 1 / base.apk,
size = 1800820,
hashcode: -908060882
}, {
Pkg = com.a.b.c,
Path = /data/app / com.a.b.c - 1 / base.apk,
size = 21279534,
hashcode: 1116685502
}, {
Pkg = com.a.b.c,
Path = /data/app / com.a.b.c - 1 / base.apk,
size = 21279534,
hashcode: 1116685502
}]
这是一些肮脏的实现,但这不是我想要的...
private final class DuplicateFilterArrayList<E> extends ArrayList<E> {
private DuplicateFilterArrayList() {
}
@Override
public boolean add(E object) {
if (object instanceof MyClass) {
if (!contains(object)) {
return super.add(object);
} else {
Logger.error(TAG, "Object already exists go home");
return false;
}
} else {
throw new IllegalArgumentException("Unsupported Object type " + object.getClass().getSimpleName());
}
}
@Override
public boolean contains(Object object) {
if (object instanceof MyClass) {
MyClass otherMyClassObjec = (MyClass) object;
for (E myClassItem : this) {
MyClass newMyClass = (MyClass) myClassItem;
if (newMyClass.equals(otherMyClassObjec) && newMyClass.hashCode() == otherMyClassObjec.hashCode()) {
return true;
}
}
}
return false;
}
}
在添加到列表之前,通过使用Collection上的contains
方法(在这种情况下为List)检查实例是否已经在Collection中。 然后,可以选择不再添加(如果已包含)。 如果您已正确实现equals和hashCode方法,则该方法应该起作用。
创建您自己的扩展ArrayList的类(MYArrayList)。 将返回类型设为列表本身。 其余的都一样。
列表列表=新的MyArrayList
MyArrayList扩展ArrayList <>
重写MyArrayList的add方法,以便在向列表中添加MYClass之前检查其列表是否已包含它。
但是请记住,这会降低性能,因为它会遍历list中的所有元素,只是为了检查插入是否重复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.