当我list集合为List<string> list 时候当我们
测试如下代码返回:
List<String> liststring=new ArrayList<>();
liststring.add("张三");
liststring.add("李四");
String string="李四";
if (liststring.contains(string)) {
System.out.println("true list中包含 string");
}else {
System.out.println("false list中不包含 string");
}
答应结果如下:说明此时contain()可以判断当前list集合存在已有的string对象
但是当list为List<User> listUser = new ArrayList<User>();
user对象为:
public class User {
private String name;
private Integer age;
public User() {
super();
}
public User(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
测试如下代码:
List<User> listUser = new ArrayList<User>();
User user1 = new User("张三",18);
listUser.add(user1);
User user2 = new User("李四",19);
listUser.add(user2);
User user3 = new User("王五",20);
listUser.add(user3);
User user4 = new User("赵六",21);
listUser.add(user4);
System.out.println(listUser); //创建一个LIst<User>对象数组
User user5 = new User("张三",18); //张三 130 是否在List<User>中 在这个数组中返回true 没有返回false
if(listUser.contains(user5)){
System.out.println(true);
}else{
System.out.println(false);
}
返回:
明明user5和user1是一样的,按道理是相等的,但是返回的结果为false 苦恼了我很久
没有办法只能看看list.contain()方法的底层源代码:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/*
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
* or -1 if there is no such index.
*/
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;
}
底层就是遍历list然后依次与所需要判断的object做equal()方法比较
其实底层就是调用的user5.equal(object);
发现在contains方法会调用 o.equals(elementData[i])方法,其中elementData[i]是个object类的实例。也就是说我在调用list.contains(user)时实际上比较的是user.equals(object) 这当然会返回false。
所有的对象都拥有标识(内存地址)和状态(数据),同时“==”比较两个对象的的内存地址,所以说使用Object的equals()方法是比较两个对象的内存地址是否相等,即若object1.equals(object2)为true,则表示equals1和equals2实际上是引用同一个对象。虽然有时候Object的equals()方法可以满足我们一些基本的要求,但是我们必须要清楚我们很大部分时间都是进行两个对象的比较,这个时候Object的equals()方法就不可以了,实际上JDk中,String、Math等封装类都对equals()方法进行了重写。(引用别人的话)
1.当两个string对象值时:由于生成string对象的优先常量池判断原则,两个string对象值相等其所在常量池中地址相同
所以调用equal() 可以返回true
2.当为非string类型object判断
不同的对象对应值相同,但是对应的内存地址不同调用equal()返回为false;
因此要解决我们头疼的问题:
重写equal()方法:
则user实体类重写equal方法如下:
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
User user=(User) obj;
if (this.age.equals(user.age)&&this.name.equals(user.name)) {
return true;
}else {
return false;
}
}else {
return false;
}
}
其中 :instanceof 为:
instanceof
instanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。
这里说明下:
类的实例包含本身的实例,以及所有直接或间接子类的实例
instanceof左边显式声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误
重新测试判断:
返回结果为:
现在大功告成,成功返回true;
所以当以后需要进行对象判断是需要自定义 重写object中的equal() 方法;
今天的文章java list集合中contain()方法详解–解决我们在使用时多属性对象实例判断一直返回false 困扰bug问题分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/64011.html