概述
contains方法
boolean contains(Object o)
如果此集合包含指定的元素,则返回 true 。
代码1演示
public class CollectionTest01 {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
String s1 = new String("唐三");
String s2 = new String("小舞");
c.add(s1);
c.add(s2);
String x = new String("唐三");
System.out.println(c.contains(x));
//打印true
}
}
分析
为什么会相等呢?难道比较的是内容相等吗?这里先不做回答,请看下面范例
代码2演示
public class CollectionTest01 {
public static void main(String[] args) {
Collection<Student> c = new ArrayList<>();
Student s1 = new Student("戴沐白");
Student s2 = new Student("朱竹清");
c.add(s1);
c.add(s2);
Student x = new Student("戴沐白");
System.out.println(c.contains(x));
//打印false
}
}
class Student{
private String name;
Student(){}
Student(String name){
this.name = name;
}
}
分析
出现了两个不一样的结果,根据我们前面的分析,难道不是比较的内容相同吗?此时来看看contains的底层源码
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
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;
}
contains方法底层调用的是equals方法。再来分析第二个代码,我们会发现Student引用类型并没有重写equals方法,如果没重写那么就会调用父类的equals方法,它的父类是Object类,跟进Object类的equals方法。
public boolean equals(Object obj) {
return (this == obj);
}
此时发现比较的是内存地址。
代码3演示
public class CollectionTest01 {
public static void main(String[] args) {
Collection<Student> c = new ArrayList<>();
Student s1 = new Student("唐三");
Student s2 = new Student("小舞");
c.add(s1);
c.add(s2);
Student x = new Student("唐三");
//重写equals方法之后
System.out.println(c.contains(x));
//true
}
}
class Student{
private String name;
Student(){}
Student(String name){
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || !(o instanceof Student)) {
return false;
}
//如果名字一样,表示同一个人。 不再比较内存地址。
Student student = (Student) o;
return Objects.equals(name, student.name);
}
}
当重写了equals方法后,就会得到我们想要的结果
remove方法
remove(Object o)
从该集合中删除指定元素的单个实例(如果存在)。
代码1演示
public class CollectionTest01 {
public static void main(String[] args) {
Collection<Student> c = new ArrayList<>();
Student s1 = new Student("唐银");
Student s2 = new Student("小舞");
c.add(s1);
c.add(s2);
Student x = new Student("唐银");
//重写equals方法之前
System.out.println(c.remove(x));
//false
}
}
class Student{
private String name;
Student(){}
Student(String name){
this.name = name;
}
}
代码2演示
public class CollectionTest01 {
public static void main(String[] args) {
Collection<Student> c = new ArrayList<>();
Student s1 = new Student("戴沐白");
Student s2 = new Student("朱竹清");
c.add(s1);
c.add(s2);
Student x = new Student("戴沐白");
//重写equals方法之后
System.out.println(c.remove(x));
//true
}
}
class Student{
private String name;
Student(){}
Student(String name){
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || !(o instanceof Student)) {
return false;
}
//如果名字一样,表示的是同一个人。 不再比较内存地址。
Student student = (Student) o;
return Objects.equals(name, student.name);
}
}
remove底层源码
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
在删除的时候也会调用equals方法去比较内容是否相同,如果没重写equals方法,将会调用其父类(Object)的equals方法去比较内存地址是否相同,这样可能不会删除我们想删除的对象。
总结
加入集合中的类型一定要重写equals方法。不重写比较的是内存地址,重写了比较的是内容。
最后
以上就是高大苗条为你收集整理的JAVA - 集合 -- contains,remove方法详解(包含底层源码分析)的全部内容,希望文章能够帮你解决JAVA - 集合 -- contains,remove方法详解(包含底层源码分析)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复