簡體   English   中英

equals和hasCode無法正常工作

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM