List:

  ArrayList

    首先我们来看看jdk的ArrayList的add方法的源码是如何实现的:     

    public boolean add(E e) {
      ensureCapacityInternal(size + 1); // Increments modCount!!
      elementData[size++] = e;
      return true;
    }

    在AarryList类有如下数组的定义

/**
    * The array buffer into which the elements of the ArrayList are stored. --这是个存储ArrayList元素的数组
    * The capacity of the ArrayList is the length of this array buffer.  ---ArrayList的长度即是数组的长度
    */
    private transient Object[] elementData;

  综上所看,ArrayList底层存储的实现是通过一个数组来实现的

LinkedList

  上源码:

  /**
  * Pointer to first node.
  * Invariant: (first == null && last == null) ||
  * (first.prev == null && first.item != null)
  */
  transient Node<E> first;

  /**
  * Pointer to last node.
  * Invariant: (first == null && last == null) ||
  * (last.next == null && last.item != null)
  */
  transient Node<E> last;

  /**
  * Links e as last element.
  */
  void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
      first = newNode;
    else
      l.next = newNode;
    size++;
    modCount++;
   }

//在ArrayList内部是有这么一个作为"节点"的内部类的

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
      this.item = element;
      this.next = next;
      this.prev = prev;
    }
  }

个人理解:至此可以猜测到LinkedList底层实现是链表;这里代码只是列举了往集合末尾添加元素的情况,具体看linkLast(E e)这个方法

linkLast方法内会根据参数e生成Node,再根据tail具体情况,修改生成node的pre/next指向,存储形式也就是链表啦

  Map:

      map的底层实现是  数组+链表

           描述一下map存储key-value的过程:

             key和value两个对象put到map的时候,会被封装成Entry<K,V>实体对象;put过程会根据K值生成一个hash码值(int类型,不同的key可能会生成相同的hash码)

                   这个hash码会被当成数组的索引/下标(index),数组的每个下标对应一个hash码,而一个hash码对应一个链表(链表存储着具有相同hash码的对象)

                  比如: 现在要  map.put("aa","123");  "aa"对应的hash码是121

                                         map.put("bb","123"); "bb"对应的hash码也是121  执行put操作的时候程序会先到数组找到下标为121(也就是hash的数值)的链表,再通过链表存储put进来的对象

         具体代码:

    

    /**
    * Associates the specified value with the specified key in this map.
    * If the map previously contained a mapping for the key, the old
    * value is replaced.
    *
    * @param key key with which the specified value is to be associated
    * @param value value to be associated with the specified key
    * @return the previous value associated with <tt>key</tt>, or
    * <tt>null</tt> if there was no mapping for <tt>key</tt>.
    * (A <tt>null</tt> return can also indicate that the map
    * previously associated <tt>null</tt> with <tt>key</tt>.)
    */
    public V put(K key, V value) {
      if (key == null)
        return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);  //找出数组对应的下标
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {  //找到数组内对应下标的链表对象
          Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  //原先key已经存在时,覆盖操作
          V oldValue = e.value;
          e.value = value;
          e.recordAccess(this);
          return oldValue;
        }
      }

      modCount++;
      addEntry(hash, key, value, i);//原先不存在key对应的Entry则在链表后添加
      return null;
     }

Set

         set的特点是无序,不重复

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

    public boolean add(E e) {
      return map.put(e, PRESENT)==null;
    }

以上是HashSet源码,可以看出HashSet底层是通过Map来实现的,不重复实现:e的hash值相同时,Map会采取覆盖的形式,这样就不会有重复了

Map的无序也就自然导致了HashSet的无序了(hash值求法?HashCode与equals)

"打完收工"....

Java集合类的底层实现探索的更多相关文章

  1. Java集合详解8:Java集合类细节精讲

    今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http://cmsblogs.com/?cat=5 具体 ...

  2. java集合类TreeMap和TreeSet

    看这篇博客前,可以先看下下列这几篇博客 Red-Black Trees(红黑树)                                         (TreeMap底层的实现就是用的红黑 ...

  3. Java集合类--温习笔记

    最近面试发现自己的知识框架有好多问题.明明脑子里知道这个知识点,流程原理也都明白,可就是说不好,不知道是自己表达技能没点,还是确实是自己基础有问题.不管了,再巩固下基础知识总是没错的,反正最近空闲时间 ...

  4. Java集合类: Set、List、Map、Queue使用场景梳理

    本文主要关注Java编程中涉及到的各种集合类,以及它们的使用场景 相关学习资料 http://files.cnblogs.com/LittleHann/java%E9%9B%86%E5%90%88%E ...

  5. Java集合类: Set、List、Map、Queue使用

    目录 1. Java集合类基本概念 2. Java集合类架构层次关系 3. Java集合类的应用场景代码 1. Java集合类基本概念 在编程中,常常需要集中存放多个数据.从传统意义上讲,数组是我们的 ...

  6. 基础知识《六》---Java集合类: Set、List、Map、Queue使用场景梳理

    本文转载自LittleHann 相关学习资料 http://files.cnblogs.com/LittleHann/java%E9%9B%86%E5%90%88%E6%8E%92%E5%BA%8F% ...

  7. java集合类(五)About Map

    接上篇“java集合类(四)About Set” 这次学完Map之后,就剩队列的知识,之后有关java集合类的学习就将告一段落,之后可能会有java连接数据库,I/O,多线程,网络编程或Android ...

  8. java集合类(四)About Set

    接上篇:java集合类(三)About Iterator & Vector(Stack) 之前,在比较java常见集合类的时候,就了解到一点有关Set的特性.实现类及其要求等,读者可以去温习下 ...

  9. java集合类(三)About Iterator & Vector(Stack)

    接上篇:java集合类学习(二) Talk about “Iterator”: 任何容器类,在插入元素后,还需要取回元素,因为这是容器的最基本工作.对于一般的容器,插入有add()相关方法(List, ...

随机推荐

  1. thinkphp5.1 退出登陆操作

    使用Session:: 静态方法即可

  2. springboot项目创建

    1.在eclipse中创建springboot项目,右键找到New,然后找到Spring Starter Project, 如果menu中找不到Spring Starter Project就选择oth ...

  3. 移动端ios下H5的:active样式失效的解决方法

    在body上绑定一个touchstart事件,空函数就行: document.body.addEventListener('touchstart', function(){}, false) 或者在b ...

  4. springBoot、SpringCloud 常用注解

    1,@SpringBootApplication是springboot启动类的入口注解,标注在主启动类上:2,@EnableEurekaServer 是eureka服务端启动,接受其他服务注册进来,标 ...

  5. webapi+ajax跨域问题及cookie设置

    最近小玩了点东西,发现简单的东西总能遇到点问题 1.webapi跨域设置 [EnableCors(origins: "*", headers: "*", met ...

  6. php导出excel不使用科学计数法

    在变量前后拼接上制表符 foreach($orderList as $k=>$v){ $orderList[$k]['pos_id'] = "\t".$v['pos_id'] ...

  7. 常用vi命令

    i  在当前光标处插入字符,并进入编辑模式 o 在当前光标插入下一行 x 从当前光标处向后删除一个字符. dd 删除当前光标处所在行 :q! 强制退出不保存 :q 退出(文本有改动则警告) :w 保存 ...

  8. jq动画设置图片抽奖

    (因为自己是前端刚入门的小白所以中间出现很多问题,不过这对于我来说就是一次经验的积累) 预想效果:点击"开始",图片循环旋转,不是同时的效果,而是有一定的时间差.点击"开 ...

  9. Linux Apache配置https访问

    配置https访问 该环境是rh254课程配套的一个环境,不过配置方法步骤相同. 要求: 使用虚拟主机技术部署两个网站: 网站1: 绑定域名 www0.example.com 目录在 /srv/www ...

  10. mysql与cmd,中文乱码

    图中第一次select, 通过navicat插入表中的, 下面的这次select结果,是直接在命令行中插入的,中文就显示了两个问号...搞不懂咋回事..我是win10家庭版系统.....希望各位道友谨 ...