Java之ArrayList源码分析(第七篇:查找元素)

(注意:本文源码基于JDK1.8)

前言

    ArrayList是基于数组的线性表容器,我们已经学习了

1、添加元素

2、删除元素

3、修改元素

现在学习一下ArrayList获取元素(查找元素)的代码原理,保存到ArrayList的元素对象,只有查找出来才能继续使用,遍历元素单独总结,本篇不再提及遍历元素

get()方法:指定下标获取元素(注意:第一个元素的下标是0)

indexOf()方法:从ArrayList对象持有的数组的第一个元素开始,查找某个元素对象的下标(从左到右,第一次匹配到的元素下标,后面有重复的不管)

lastIndexOf()方法:与indexOf()方法相反,它是从ArrayList对象持有的数组对象的最后一个元素开始,查找某个元素的下标(从右到左,第一次匹配到的元素下标即会返回,后面有重复的不管)

contains()方法:用来检查ArrayList是否包含某个元素

get()方法分析

    public E get(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

        return (E) elementData[index];
    }

用于获取指定下标处元素的方法,get(int)方法是List接口规范的抽象方法,ArrayList的父类AbstractList以及ArrayList都实现了List接口,ArrayList具体实现了get(int)方法!我们看看它是如何实现的……

1、首先检查下标是否合法

传入的局部变量index表示下标,如果下标index大于等于当前ArrayList实际持有的元素总数size值,会直接抛出一个IndexOutOfBoundsException异常对象,IndexOutOfBoundsException包含的异常信息则由一个outOfBoundsMsg()方法返回的字符串构成,ArrayList对象持有的size有两个作用,一个是作为即将插入新元素的下标,另一个是表示ArrayList对象实际保存的元素总数,合理的范围是指:对应的下标处必须保存着元素,显然只有0到size - 1处保存着元素对象,所以当传入的index无论是大于还是等于size,一定没有元素的(竟然没有检查小于0的下标)

2、通过数组下标获取元素对象

将下标index传入到ArrayList对象持有的底层数组对象elementData中,执行数组下标访问,获取的元素对象为Object对象,所以又做了一个根据元素的实际类型的转换,转换元素的类型为对应的类型参数E

3、向调用者返回实际保存在数组对象中的元素对象

indexOf方法()分析

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

indexOf()方法用于获取指定元素对象的下标,因为ArrayList支持null元素的存储,所以获取某个元素对象的下标时,在indexOf()方法的代码块中,将null元素与非null元素查找下标的逻辑均分开处理!

1、获取null元素下标的业务逻辑

当传入的参数o为null时,从ArrayList对象持有的elementData数组对象的最左侧开始,向右侧进行遍历查找null元素,当找到一个匹配的null元素,indexOf()方法会返回该元素所在的下标,如果查找到右侧的结尾,也就是size - 1 处的下标位置仍没有找到匹配的null元素,indexOf()方法会返回给调用者一个-1……

2、获取非null元素下标的业务逻辑

此时传入的参数o不为null,同样是遍历,不过比较的方式改为了元素对象的equals()方法进行判断,当两个对象的equals()方法判断为相等时,表示找到匹配的元素,此时返回元素所在的下标,同样也是到达size - 1的边界下标处

3、处理没有找到元素对象的情况

当仍然没有找到匹配的元素存在时,indexOf()方法会返回一个-1

PS:对于null元素,通过==判断是否相等

PS:对于Object对象的元素,通过每个对象拥有的equals()方法判断是否相等

lastIndexOf()方法分析

    public int lastIndexOf(Object o) {
        if (o == null) {
            for (int i = size-1; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = size-1; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

lastIndexOf()方法与上面indexOf()方法的唯一的区别是:lastIndexOf()方法是从底层数组的最后一个存在的元素开始,一直向左侧遍历查找指定元素的下标

1、元素为null

初始化第一个存在的元素下标为size-1,如果查找到某个元素为null,则直接返回临时存储的下标值,即局部变量i的值

2、元素为Object

同样初始化第一个存在的元素下标为size-1,每次将传入的元素对象与数组中取出来的元素对象,通过equals()方法比较,如果相等,则返回每次遍历时的下标,因为是从右向左遍历元素,所以局部变量i的值会每轮减去1,循环的终止条件是i < 0时,因为左侧最后一个元素的下标是0

3、没有找到匹配的元素

向调用者返回-1,表示传入的元素对象并没有在ArrayList存储

contains()方法分析

    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

用于检查是否包含某个元素的方法,传入的参数为元素对象

1、获取元素对象所在的下标

通过indexOf()方法可以获取元素对象在ArrayList对象持有的数组对象中的下标,如果没有找到对应的元素,indexOf()方法会返回-1

2、检查获取到的元素下标并进行比较

使用indexOf()的返回值与0进行比较,如果元素对象存在,则indexOf()方法会返回的是大于等于0的一个值,否则indexOf()方法会返回-1

3、向调用者返回比较的结果

true表示包含

false表示不包含

总结

1、get()方法用于通过下标获取到元素对象

2、查找某个元素对象的下标,则可以根据需求,选择从左到右、或者从右到左去查找元素对象的下标,只要匹配到任意一个元素,结果即返回,注意多个重复的情况

3、包含与不包含则是通过获得某个元素对象的下标进行的,只要获取的下标大于等于0,那么一定就属于包含某个元素了!

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值