List接口的contains方法与remove方法

一.contains方法用于判断集合中是否存在某元素。比如:在集合中存入一个字符串”111“

import java.util.ArrayList;
import java.util.List;

public class Contains {
	
	public static void main(String[] args) {
		List arrayList = new ArrayList<>();
		arrayList.add("111");
		arrayList.add(null);
		Student liMing = new Student();
		arrayList.add(liMing);
		
		System.out.println(arrayList.contains("111"));//输出true
	}
}

contains方法的源码如下:

 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&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;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;
    }

执行contains方法时先判断是否传入为空,如果为空就逐个遍历集合中是否有空元素;
如果不是空就利用String类重写的equals方法来比较字符串是否一样。
所以contains方法的逻辑可以用一个三目运算符表示:o ==null ? e ==null : o.equals(e)

o指传入方法的具体值,e指集合中的某一个元素,该三目表达式有以下四种情形:
1、如果o的值为null,则只有集合中存在null元素才会返回true;
2、如果o为String类型的对象,则只有集合中存在满足o.equals(e)条件的元素e时才会返回true ,其实质是运行时类型相同的前提下比较两者字符串是否完全相同
3、如果o为基本数据类型包装类对象,则只有集合中存在满足o.equals(e)条件的元素e时才会返回true,其实质是在两者运行时类型相同的前提下比较两者的值是否相等
4、如果o为自定义类类型对象,则只有集合中存在满足o.equals(e)条件的元素e时才会返回true,其实质是在两者运行时类型相同且自定义类没有重写equals方法的前提下比较两者的地址是否相等。

其中第四条是因为自定义类间接继承自Object类,在没有重写equals方法时使用的是Object类的equals方法。而Object类的equals方法就是“==”。所以比较的是地址。但是这样的话实际上是有些问题的。如果创建一个学生类,仅根据学号判别是否为同一个学生,这时便会有些问题。例如:

import java.util.ArrayList;
import java.util.List;

public class Contains {
	
	public static void main(String[] args) {
		List arrayList = new ArrayList<>();
		arrayList.add("111");
		arrayList.add(null);
		Student liMing = new Student();
		liMing.setStudenId("123");
		arrayList.add(liMing);
		
		Student wangMing = new Student();
		wangMing.setStudenId("123");
		
		
		System.out.println(arrayList.contains(wangMing));
	}
}

两个自定义对象的学号一样,应该显示true,但是输出为false。这是要是把自定义类的equals改写下就能输出true:

public class Student {
	private String studenId;

	public String getStudenId() {
		return studenId;
	}

	public void setStudenId(String studenId) {
		this.studenId = studenId;
	}
	
	
	public boolean equals(Object stu) {
		if(stu instanceof Student) {
			Student student;
			student = (Student)stu;
			return this.studenId.equals(student.studenId);
		}
		return false;
	}
}
import java.util.ArrayList;
import java.util.List;

public class Contains {
	
	public static void main(String[] args) {
		List arrayList = new ArrayList<>();
		arrayList.add("111");
		arrayList.add(null);
		Student liMing = new Student();
		liMing.setStudenId("123");
		arrayList.add(liMing);
		
		Student wangMing = new Student();
		wangMing.setStudenId("123");
		
		
		System.out.println(arrayList.contains(wangMing));
		
	}
}

这时输出为true。

二.remove(int index) 移除列表中指定位置的元素,并返回被删元素,删除位置后面的元素(如果有)向前移动。
remove(Object o) 则是从List集合中移除第一次出现的指定元素,移除成功返回true,否则返回false。当且仅当List集合中含有满足(o==null ? get(i)==null : o.equals(get(i)))条件的最低索引i的元素时才会返回true

我们可以看到,remove跟contains其实是一样的判断逻辑。所以对源码的分析跟小标题一的分析类似,得到的四条结论也是一样的。

发布了74 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/naruhina/article/details/87906766