如果你有什么事,一定要告诉我,反正我也解决不了。
前言
越来越觉得基础知识的重要性了,追求新框架,新技术其实没有多大意义,那东西学学就会用了。还得是基础知识更加重要。
数组和链表
数组和链表是数据结构中最基本的知识了,长篇大论我就不讲了。我是专门学Java的,所以就直接阅读Java中对应的两个类——ArrayList
与LinkedList
。一般读一遍源码就会很清晰了。
ArrayList源码阅读
我们经常说ArrayList底层是用数组实现的,其实我们点开源码一看就知道。
这个就是我们说的那个数组。我们调用add()
方法,其实就是往这个数组里添加对象。
接下来我们再看看调用add()
方法会发生什么
我们发现它调用了一个ensureCapacityInternal()
方法,然后再将对象放进数组里。这个方法一看就是跟它的扩容机制有关系。我们继续进入这个方法看一看
我们看到,它在真正调用扩容方法之前又进行了一些判断。分析一下就知道,这里判断它是不是空对象,如果是空对象,就将默认数组大小10这个参数传递给扩容方法。结合扩容方法可知,它是在你第一次添加数据的时候,将数组扩容到10,而不是在创建的时候在无参构造器里直接设置成大小为10的数组。
这里就是它的真正的扩容操作,1.5倍扩容,且用到了右移运算符。看源码发现里面的左移或者右移运算还是不少的。
总结一下就是,ArrayList新增的时候会先检查数组是不是满了,如果数组容量不够了,就会1.5倍扩容。
接下来我们再看看它的删除方法
这个方法就是ArrayList的删除操作,它将你要删除的元素后边的都往前移动一位,再将最后一位置为null。
它的查询就更简单了,就是一个for循环而已,就不说了。
LinkedList源码阅读
我们都知道,LinkedList
底层是用链表实现的。我们看看源码就很清晰了。
它的节点是用这么一个静态内部类存储的。是一个双向链表。有两个引用分别指向这个节点的前一个和后一个。
接下来我们看看它是如何新增元素的。
这就是双向链表的常规操作,把最后一个节点的next指向新节点,新节点的prev指向最后一个节点。这样新节点就变成了最后一个节点,加入到了链表里。
删除节点也同样很简单
就是把当前节点的前节点和后节点连起来就可以了。很常规的操作。
但是查找第几个元素的时候,它就很聪明的分成两半来找
就这么一个小小的判断直接将循环次数减半。
关于栈和队列就不详细说了。下一篇我们直接开始聊一聊二叉树。