F3达人 nino

发布时间:2019-08-05 15:35:17编辑:auto阅读(1394)

    F3达人

                ---JDK掘金

    什么是F3达人

    如何成为F3达人

    JDK掘金之瞅瞅List

     

    文笔不好,就乱说几句。在下此处说的f3 并不是BYDf3,此乃 eclipse 上的f3.  因为鄙人的环境是windowslinux这样的高深环境,一般不怎么用。 再个大家可能更多开发环境也是windows,所以就windows上的eclipse默认源码查看键F3来展开这个小系列。

    解释了f3不够,咱的目标是要成为f3达人!在这肉欲横飞的世界里,达人到处都有,干嘛的都有,唯独咱们此处说的达人,或者提出的F3达人还是不多见的吧 :)  所以成为这个达人,也算是个追求吧

    如何成为f3达人呢? 最简单不过了,什么时间你的键盘F3被用的破损了,估计差不多了,此处只指eclipse使用时点f3 ,其他的各位看官自己处理吧,反正网管不会给非此方法搞坏f3的人换键盘

    都是技术人,说了半天,来点干货吧。

    度娘告诉我们一个技巧:“只遍历用Arraylist,只要有修改就用linkedList,如果修改中还有遍历则是LinkedList+iterator借口遍历”。咱们称此为规则1,下文也以此引用。

    以前一些哥们对前辈或者老大说的话不会过多的思考的,所以他就很久没成为老大,或者只成为老辈,没有成为别人的前辈,甚是可惜。咱们今天换个想法,虽然度娘很猛,不过咱们还是自己多想想,多试试。

    方案一:黑盒测试

    http://blog.csdn.net/xyx139/article/details/6591420  

    这哥们比较勤恳,已经测试了,我就不重复贴码了。

    方案二:白盒一下

    码一段:

    List<String> list=new ArrayList<String>();

    list.add("1");

    list.get(0);

     

    咱们对着 add  就是一下F3 ,结果给了

    List.class -> boolean add(E e);

    一看定位到了List.class add方法。都知道List是个接口,add是个接口方法签名,没有具体实现。因为咱们用的是面向接口编程 即声明时 List<String> 而不是ArrayList<String>   此时来一下ctrl+t  。选中弹出来框中的 ArrayList即可。 此过程咱们不多说了。

    这时来到了ArrayList.class

    public boolean add(E e) {

            ensureCapacityInternal(size + 1);  // Increments modCount!!

            elementData[size++] = e;

            return true; }

    有兴趣的F3一把ensureCapacityInternal() 

    private void ensureCapacityInternal(int minCapacity) {

            modCount++;

            // overflow-conscious code

            if (minCapacity - elementData.length > 0)

                grow(minCapacity);

        }

    兴趣还存,那就在F3一把grow()

    private void grow(int minCapacity) {

            // overflow-conscious code

            int oldCapacity = elementData.length;

            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:

            elementData = Arrays.copyOf(elementData, newCapacity);

        }

    好了,到此,我们已经知道了,ArrayList底层使用数组实现的,每次add时判断一下是否超出了初始的大小,超过了就grow一下,grow中用的数组拷贝之类的方法,大家可以活学活用,今天主题不是这个,不多说他了。

    不过插一小句啊,刚才提及了,说是如果超过初始大小的话就grow。那么初始大小多大呢?

    public ArrayList() {

            this(10);

        }


    此处看到,初始大小是10.  据此,咱们可以增加一条优化使用方法。如果咱们对ArrayList的大小有个大小预期,超过10,咱们就直接调用ArrayList(int initialCapacity)  这样避免掉频繁的grow

    下面开始对get方法F3. 或许到此你还在为了成为达人,在看着烂文,呵呵。

    public E get(int index) {

            rangeCheck(index);

            return elementData(index);

        }

    实现就是,rangeCheck 检查一下是否越界。 之后就是直接返回了elementData(index);  再次F3 

    E elementData(int index) {

            return (E) elementData[index];

        }

    好了,到此看到,get直接由封装的数组直接定位返回。(小知识:汇编之所以快,因为很多都是直接寻址;java中数组的直接下标寻址也是非常快的,或许是最快的吧,咱就不断言了)

    咱们分析一下LinkedList的get方法。 因为直接知道要分析谁,直接ctrl+shift+t LinkedList  定位到 LinkedList.class

    public E get(int index) {

            checkElementIndex(index);

            return node(index).item;

    }

    Node<E> node(int index) {

            // assert isElementIndex(index);

            if (index < (size >> 1)) {

                Node<E> x = first;

                for (int i = 0; i < index; i++)

                    x = x.next;

                return x;

            } else {

                Node<E> x = last;

                for (int i = size - 1; i > index; i--)

                    x = x.prev;

                return x;

            }

        }

        最终的node(int index),代码和数组直接下标取值相比,势必慢点。通过以上F3,咱们了解了 ArrayList LinkedList 的get 方法的不同。

    好了,至此,咱们通过一路F3在JDK源码中掘金:

    1.ArrayList 底层用数组实现。初始默认大小是10 。

    2.每次add时会检测是否超出数据大小,超过的话就grow

    3.因为get(int index) 方法是调用底层的数据下标寻址,所以速度非常快;相比之下LinkedList因为底层使用链表,所以查询天生就不如数组快。

    更多的金子等待各位看官去挖了。 希望没有过多的浪费您的时间 :)

     

    PS:计划下次写一下Hash相关的

关键字