ACAC contains 和 remove深入

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);
       }

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值