Java小白学点东西(10)

1.ArrayList

大家可以借助官方API查询可以看到:

Collection下面有一个子接口叫List

List接口下面有一个实现类叫ArrayList

ArrayList底层是数组

ArrayList也是容器,可以放数据

源码分析

/**
     * Default initial capacity.
     默认的变量,变量值是10   默认的初始化的容量
     */
    private static final int DEFAULT_CAPACITY = 10;
/**
     * Shared empty array instance used for empty instances.
     声明了一个空的数组EMPTY_ELEMENTDATA 变量
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};
 /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     默认容量的空数组
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
 /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     数组的有效的容量  size 默认值是0
     */
    private int size;
 /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     构造方法,在实例化的时候调用有参数的构造
     */
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
 /**
     * Constructs an empty list with an initial capacity of ten.
     无参数的构造方法
     构造了一个初始化容量为10的空的数组
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
​
​//扩容的方法。当数组的容量不够的话,会自动扩容
 private void grow(int minCapacity) {
        // overflow-conscious code
     //oldCapacity 是老的容量
        int oldCapacity = elementData.length;//10个容量  数组里面只能放10个元素
     //newCapacity新的容量  (oldCapacity >> 1);叫位元算符
     //  int newCapacity = oldCapacity + oldCapacity * 0.5;
     //int newCapacity = 1.5 * oldCapacity;//扩容的是原来数组的1.5倍
     //原来的数据是10   扩容以后的容量是15  
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
     //扩容完以后,进行数组的赋值
     //[1,2,3,4,5,6,7,8,9,10]  原来的数组
     //[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]  在赋值一个数组这个数组容量是15
     //进行数组的扩容了,新的数组还有有老数组中的数据
        //所以使用copy方法
        elementData = Arrays.copyOf(elementData, newCapacity);
    }


经常会遇到面试题:
ArrayList处理数据的特征:
    增数据删数据比较慢。为什么?
           增加数据效率低:
               1.有可能会涉及到数组的扩容,涉及到数组的copy
               2.添加数据到指定位置的时候,会导致从添加数据位置开始整体后移
           删除数据效率低:
               从删除数据开始,数据整体前移一位
   查找快。为什么?
       用的索引进行查找的
       好比一本书,有目录。你要找某一章节,这个章节有页码数,直接翻到页码数
       页码数就是这个索引
       cpu是通过访问内存地址(数组+下标)直接定位到集合中的元素的
       
       开发中一般使用ArrayList,开发中查询偏多,因为查询比较多,增删的话相对来说会少。
       
       
      对于时间复杂度来说: 查找是1,增删是n

2.LinkedList

父接口是List

它和ArrayList是亲兄弟。但是开发中使用ArrrayList而不用LinkedList

双向链表:自行车的车链子

LinkedList是队列

队列:先进先出(比如排队做核酸,先排队的人先做核酸,后排队的后做)

栈:先进后出 (比如一群人挤电梯到一层楼,先挤进去的人在最里面,后挤进去的人在最外面,电梯停止的时候,后挤进去的先出来,先挤进去的后出来)

面试也经常问

ArrayList和LinkedList的特点和区别

ArrayList和LinkedList 都是List接口的实现类

ArrayList在查询数据的时候比较快,但是增删慢

LinkedList查询的时候慢,增删的时候快

linkedList底层是双向链表结构

查找慢:是因为使用了二分法查找的算法(二分查找法是数据结构中一种方法,大家可以度娘一下了解一下)

[1,2,3,4,5,6,7,8,9,10] 比如找3这个数,

[1,2,3,4,5] [6,7,8,9,10] 一分为2

[1,2,3,4,5] 再一分为2

[1,2,3] [4,5]

[1,2,3] 再一分为2

[1,2] [3] 找到了 3

查询的时候进行了n次 使用LinkedList查找的时候进行了n次,他不是一次就出来了

增删快:因为LinkedList底层是一个节点内部类。

开发中咱们只使用ArrayList,而不用LinkedList。因为咱们以后的网站查询使用的较多。增删较少,使用ArrayList的时候几乎不影响效率的

3.Object类

Object类是所有类的基类,其中包含有:

toString();方法

equals();方法

Object类下面的equals方法比较的是两个对象的地址,比较严格

public boolean equals(Object obj) {
 return (this == obj);
}
==比较的是内存地址和内容,比较严格

String类下面的equals比较的是内容。充分说明了一点。String类肯定重写了Object

下面的equals方法。xdm下面咱们看看源码:

public boolean equals(Object anObject) {
        //也是先看两个地址是否一致,如果两个对象的地址一致,肯定内容也一致了
     if (this == anObject) {
         return true;
     }
     if (anObject instanceof String) {
         //强转  "来一杯Java咖啡" = value
         // "来一杯Java咖啡" = anotherString.value
         String anotherString = (String)anObject;
         int n = value.length;//字符串的长度  9
         if (n == anotherString.value.length) {
             //为什么要先比较两个字符串的长度呢?
             //比较两个字符串的时候,如果长度不同,这个两个字符串肯定不相等
             //如果两个字符串长度相等的话,紧接着比较字符串的内容
             char v1[] = value;//[来,一,杯,J,a,v,a,咖,啡]
             char v2[] = anotherString.value;//[来,一,杯,J,a,v,a,咖,啡]
             int i = 0;
             while (n-- != 0) {
                 if (v1[i] != v2[i])
                     //如果这两个字符串字符数组通过循环挨个比较。如果有一个字符不相等,就返回的是false
                     return false;
                 i++;
             }
             //内容一致的话也是一个true
             return true;
         }
     }
     return false;
 }

int hashCode();方法

hashCode方法获取的是对象的hash值,也被散列码,实际上是一个十进制int类型的数值

这个值就是对象的内存地址(十六进制的)转为10进制的数据

官方手册:

如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。

常见的面试题:

为什么重写了equals方法的时候,必须重写hashCode方法?

两个对象使用equals方法进行比较的时候,如果对象一样的话,hash码可能不一样

开发时要保证hash码也必须是一样的。

假如hash码一样对象肯定一样的

4.Set集合

Set父接口是Collection

Set和List是亲兄弟

List集合的特征是:有序的,可以重复的

Set特征是:无序的,不可重复的

Set接口下面有两个实现类:

HashSet TreeSet

Set接口中没有独特的方法,就是Collection接口下面的方法

Set在开发中用的也比较少

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇智波波奶茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值