import java.util.ArrayList;
import java.util.Collection;
/*
* 1、boolean contains(Object o) 返回 true 如果集合包含指定元素,否则返回false
*
*
*
* */
public class CollectionTest04 {
public static void main(String[] args) {
Collection c = new ArrayList();
String s1 = new String("abc");// s1 = 0x1111
c.add(s1);
String s2 = new String("def");// s2 = 0x2222
c.add(s2);
String s3 = new String("abc");// s3 = 0x3333
System.out.println(c.contains(s3));
/**
* 判断是否包含S3,我推测是不包含的,因为保存的内存地址不一样,
* 虽然对象里的内存地址都指向了“abc”,但s3本身保存的内存地址和s1不一样
* ok 这样分析的没有错,的确是这样
* 但是,contains方法比较的不是s3的内存地址是否在集合中
* 看下面源码里的,
* if (o.equals(es[i])) {
* return i;
* }
* 这个o是S3
* 所以这是 s3.equals(es[i])
* s3.equals("abc") es[i] = s1嘛
* String 类型的equals比较重写了,所以是比较的内容
* 所以最终结果是true
*
*结论:contains方法,是采用equals比较的,String类型的就不是比较内存地址了、
* 就是比较内容,看这个字符串是否在集合中
*
* 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) {
* for (int i = start; i < end; i++) {
* if (es[i] == null) {
* return i;
* }
* }
* } else {
* for (int i = start; i < end; i++) {
* if (o.equals(es[i])) {
* return i;
* }
* }
* }
* return -1;
* }
*
*/
}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
/*
* contains测试
* 放在集合中的元素,一定要重写equals方法的,否则比较的是内存地址,默认调用Object类中的equals
* */
public class CollectionTest05 {
public static void main(String[] args) {
Collection c = new ArrayList();
User u = new User("miao");
c.add(u);
User uu = new User("miao");
System.out.println(c.contains(uu));
Integer it = new Integer(100);
c.add(it);
Integer it2 = new Integer(100);
System.out.println("it.equals(it2)==" + it.equals(it2));
System.out.println(c.contains(it2));
c.remove(uu);
System.out.println("应该有两个,现在有:" + c.size());
/**
*public int intValue()
*作为一个 int返回该 Integer的值。
*简单点:Integer类中重写了equals方法
*/
/**
* 刚开始,我是这样认为的:
* c.contains(uu) 根据Test03的经验,我认为这个也是用equals方法比较的
* if (o.equals(es[i])) {
* return i;
* }
* 而这个o,也就是uu,代表的是String类型的,所以重写了equals方法,所以是true
*
* 指出我的错误:
* 首先这个o是uu没错,但他是User类型的,而User类型中没有重写equals方法
* 而当你点这个equals方法,看他在哪里,结果跳到了Object类中,而User又是
* 间接继承Object类的,但是Object类中并没有重写equals方法,而我User类中
* 也没有重写equals方法,所以默认调用Object类中的equals方法
* public boolean equals(Object obj) {
* return (this == obj);
* }
* 这里比较的是内存地址,所以(o.equals(es[i]))比较的是内存地址,而uu并没有添加到
* c集合中,所以是false的
*
* public int indexOf(Object o) {
* return indexOfRange(o, 0, size);
* }
*
* int indexOfRange(Object o, int start, int end) {
* Object[] es = elementData;
* if (o == null) {
* for (int i = start; i < end; i++) {
* if (es[i] == null) {
* return i;
* }
* }
* } else {
* for (int i = start; i < end; i++) {
* if (o.equals(es[i])) {
* return i;
* }
* }
* }
* return -1;
* }
*
*
* 同理这里remove也是重写了equals方法,如果你删除uu ,Java认为uu和u是一样的
* 因为uu就是u,因为他这里是调用的equals方法比较的,而你有重写了equals方法,User类的
*
* 这里你删除100(it2),也会把it删除的
* public boolean remove(Object o) {
* final Object[] es = elementData;
* final int size = this.size;
* int i = 0;
* found: {
* if (o == null) {
* for (; i < size; i++)
* if (es[i] == null)
* break found;
* } else {
* for (; i < size; i++)
* if (o.equals(es[i]))
* break found;
* }
* return false;
* }
* fastRemove(es, i);
* return true;
* }
*
*/
}
}
class User{
private String name;
public User(String name) {
this.name = name;
}
public User() {
}
//开始重写equals方法(其实是系统默认的),结果就是true了
/*@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(name, user.name);
}*/
//自己写,复习一下
public boolean equals(Object o){
if(o == null || !(o instanceof User)) return false;
if(o == this) return true;
User u = (User)o;
//如果名字一样表示同一个人,(不再比较内存地址了)
//放心,这里的u肯定不是null,也肯定不是其他类型的,看第一行判断
return u.name.equals(this.name);
}
/**
* 重点:
* 1、把集合继承结构图背会(理解不深刻,也要会说)
* 2、把Collection接口中常用方法测试几遍
* 3、把迭代器弄明白
* 4、Collection接口中remove方法和contains方法底层都会调用equals方法,弄明白
*
*/
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* 集合中的迭代器
* 结论:当集合结构放生改变时,迭代器必须重新获取
* 异常:java.util.ConcurrentModificationException
*
* 关于集合元素中的remove
* 删除元素,之后,集合结构发生了改变,但是下次循环迭代器
* 没有重新获取,所以会发生异常,迭代中不能这么干
*
* 在迭代元素的过程中,一定要使用哦迭代器Iterator的remove方法,不要使用集合自带的remove方法
*/
public class CollectionTest06 {
public static void main(String[] args) {
Collection c = new ArrayList();
//如果把迭代器放在还集合的前面会出什么问题
Iterator iterator = c.iterator();
//java.util.ConcurrentModificationException
//注意:当集合结构放生改变时,迭代器必须重新获取
//注意:这里的可不是123,而是Integer 对象的内存地址
c.add(1);
c.add(2);
c.add(3);
Iterator it = c.iterator();
//重复使用迭代器,也就是更新迭代器,没有问题
while(it.hasNext()){
System.out.println("集合的长度:" + c.size());
Object o = it.next();
/**
* 删除元素,之后,集合结构发生了改变,但是下次循环迭代器
* 没有重新获取,所以会发生异常
* 根本原因:集合中元素删除了,但没有更新迭代器
* 使用迭代器删除可以吗?
*/
// c.remove(o); 直接通过集合删除元素,没有通知迭代器(导致迭代器的快照和原始状态不同)
// 迭代器删除时,会自动更新迭代器,并且更新集合
it.remove();//删除的一定是迭代器指向的当前元素
System.out.println(o);
}
}
}