【问题标题】:List<MyModel>.contains(MyModel) java is not workingList<MyModel>.contains(MyModel) java 不工作
【发布时间】:2019-07-24 03:56:09
【问题描述】:

我的 MyModel 类包含:

private int value;

public int getValue() {
    return value;
}

public void setValue(int value) {
    this.value = value;
}

现在我已经填充了 MyModel 类:

private final List<MyModel> listModel = new ArrayList<>();
private Mymodel myModel;

 myModel= new MyModel ();
 myModel.setValue(1);
 myModel.setValue(2);
 myModel.setValue(3);
 listModel.add(myModel);

我想知道 listModel 是否包含 myModel

listModel.contains(myModel)

我进行了一些搜索,我知道 contains 使用了等号,但我正在寻找找到解决方案的正确方法。 提前致谢

【问题讨论】:

  • 除了实现equals之外,真的没有其他方法可以做到这一点。你应该实现equals
  • 现代 IDE 将帮助您正确实施它
  • 如果您有一个可以唯一标识 MyModel 的原始字段,例如 int id,那么您可以从 List 获取字段列表并在其中搜索 myModel.id。
  • "contains 使用了 equals,但我正在寻找找到解决方案的正确方法" - 为 MyModel 实现 equals() 是稍后使用 contains() 的正确方法。

标签: java arraylist contains


【解决方案1】:

尝试运行以下代码,我已对其进行了修改并添加了日志,现在您可以检查控制台上打印的输出: 我建议你使用 equals() 检查对象。

class MyModel {
private int value;

public int getValue() {
    return value;
}

public void setValue(int value) {
    this.value = value;
}

@Override
public String toString() {
    return "MyModel{" +
            "value=" + value +
            '}';
}

}

final List<MyModel> listModel = new ArrayList<>();
    MyModel myModel;

    myModel= new MyModel();
    myModel.setValue(1);
    myModel.setValue(2);
    myModel.setValue(3);
    listModel.add(myModel);
    //here your myModel object has '3' value and list has [3], So this will return `true`
    System.out.println("myModel=>"+myModel.toString()+"-->List = "+listModel.toString()+",, CONTAINS. =>"+listModel.contains(myModel));

    myModel= new MyModel();
    myModel.setValue(8);
    listModel.add(myModel);
    //here your myModel object has '8' value and list has [3,8], So this will return `true`
    System.out.println("myModel=>"+myModel.toString()+"-->List = "+listModel.toString()+",, CONTAINS. =>"+listModel.contains(myModel));

    myModel= new MyModel();
    myModel.setValue(100);
    //here your myModel object has '100' value and list has [3,8], So this will return `false`
    System.out.println("myModel=>"+myModel.toString()+"-->List = "+listModel.toString()+",, CONTAINS. =>"+listModel.contains(myModel));

【讨论】:

    【解决方案2】:

    如果您查看ArrayList 类中contains 的实现,您会发现它在内部使用equals 方法来查找对象:

    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
    
    public int indexOf(Object o) {
        return indexOfRange(o, 0, size);
    }
    
    int indexOfRange(Object o, int start, int end) {
        Object[] es = elementData;
        if (o == null) {
           ...
        } else {
            for (int i = start; i < end; i++) {
                if (o.equals(es[i])) { //calling overridden equals of the object instance, else it will revert to the Object's equals which simply compares the reference 
                    return i;
                }
            }
        }
        return -1;
    }
    

    所以你需要为你的MyModel 类创建equalshashCode。您可以借助您正在使用的 IDE 为您生成它:

    举个例子:

    class MyModel{
        private int value;
    
        public int getValue() {
            return value;
        }
    
        public void setValue(int value) {
            this.value = value;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof MyModel)) return false;
            MyModel myModel = (MyModel) o;
            return value == myModel.value;
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(value);
        }
    }
    

    【讨论】:

    • 对象(应该)总是等于它自己!最初的实现Object.equals(..)this == another。 OP 不会更改原始 myModel 对象的引用,因此 contains(myModel) 必须在没有自己的 equals(...) 的情况下工作。
    【解决方案3】:

    检查包含的唯一方法是覆盖equals() 方法。如果您检查 contains 方法是如何在 ArrayList 中实现的,您可以轻松找到它。 contains() 方法将调用 indexOf() 方法,该方法将返回列表中元素的索引。如果索引大于0,那么contains()方法会返回true。

    让我们看看indexOf()方法是如何实现的。

    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }
    

    这意味着indexOf() 方法只是遍历列表中的元素并在您的MyModel 类中调用equals() 方法。

    因此,如果不覆盖 Object 类中的 equals() 方法,则没有其他方法可以检查包含项

    【讨论】:

    • 对象(应该)总是等于它自己!最初的实现Object.equals(..)this == another。 OP 不会更改原始 myModel 对象的引用,因此 contains(myModel) 必须为 true 而无需编写自己的 equals(...)
    猜你喜欢
    • 2018-11-18
    • 2020-03-02
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2012-10-30
    相关资源
    最近更新 更多