精华内容
下载资源
问答
  • 常规思路由于搜索树的中序排列是升序的,这点非常好用,意味着我们可以直接中序遍历二叉树,然后保存在一个数组中,再降这个有序数组转化链表即可。本题特点但是本题要求额外的空间复杂度必须控

    本篇博文主要在参考下面这篇总结二叉树常见算法题的博文基础上修改而成,这篇文章总结得非常棒,建议大家都读读-[面试大总结之二:Java搞定面试中的二叉树题目]

    常规思路

    由于搜索树的中序排列是升序的,这点非常好用,意味着我们可以直接中序遍历二叉树,然后保存在一个数组中,再降这个有序数组转化为链表即可。

    本题特点

    但是本题要求额外的空间复杂度必须控制在O(1),也就是说必须在遍历的过程中完整链表的操作,所以会设计很多指针转换。

    二叉树的题目多半是可以用递归来做的,这是由二叉树的结构导致的,所以一般性的题目,首先要将它往递归的方面思想,往往会使问题变得更加简单。

    代码部分

    public static TreeNode convert(TreeNode root){
        root = convert2Link(root);
        /*这里注意的是,利用递归的思想,利用convert2Link我们将左右子
        树分别为了链表,然后再与root节点链接成为一个完整的链表,返回
        的是中间节点,也就是我们传进去的root对应的节点,所以我们用下
        面循环讲root指向链表的开头*/
        while(root.left != null){
            root = root.left;
        }
        return root;
    }
    
    public static TreeNode convert2Link(TreeNode root){
        if(root == null ||(root.left == null && root.right == null));
        TreeNode tmp = null;
        if(root.left != null){
            tmp = convert2Link(root.left);
            while(tmp.right != null){
                tmp = tm.right;
            }
            tmp.right = root;
            root.left = tmp;
        }
    
        if(root.right != null){
            tmp = convert2Link(root.right);
            while(tmp.left != null){
                tmp = tmp.left;
            }
            tmp.left = root;
            root.right = tmp;
        }
        return root;
    }
    
    展开全文
  • Java8 HashMap

    2018-07-16 14:40:59
    Java8 HashMap,当一条链长度超过8,便会转化成红黑树。存储结构HashMap结构:数组+链表+红黑树对于之前的版本数组+链表来说,当hash冲突多的时候,会导致一个桶上的链表很长,查找的复杂度O(n)。而Java8 HashMa.....

    阅读原文

    摘要: HashMap结构:数组+链表+红黑树。对于之前的版本数组+链表来说,当hash冲突多的时候,会导致一个桶上的链表很长,查找的复杂度O(n)。而Java8 HashMap,当一条链长度超过8,便会转化成红黑树。

    存储结构

    HashMap结构:数组+链表+红黑树

    对于之前的版本数组+链表来说,当hash冲突多的时候,会导致一个桶上的链表很长,查找的复杂度O(n)。而Java8 HashMap,当一条链长度超过8,便会转化成红黑树。红黑树特点:插入、查找、删除的时间复杂度为O(log n)。

    红黑树的关键性质:从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。这样最坏情况也可以是高效的。

    每个节点使用Node存储信息,如果转化为红黑树,则使用TreeNode存储树的节点。

    put

    通过计算后的hash值对应table的下标,找到table第一个节点,有以下情况:
    1)桶为空,则新建节点Node作为桶上第一个节点
    2)节点为红黑树节点,则直接往红黑树插入节点
    3)其余情况即链表:通过e=p.next、p=e循环找到链尾,在链尾插入新节点。如果长度超过8,则对链表进行红黑树转化。

    putVal源码如下:

        final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                       boolean evict) {
            Node<K,V>[] tab; Node<K,V> p; int n, i;
            if ((tab = table) == null || (n = tab.length) == 0)
                n = (tab = resize()).length;
            if ((p = tab[i = (n - 1) & hash]) == null)
                tab[i] = newNode(hash, key, value, null);
            else {
                Node<K,V> e; K k;
                if (p.hash == hash &&
                    ((k = p.key) == key || (key != null && key.equals(k))))
                    e = p;
                else if (p instanceof TreeNode)
                    e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
                else {
                    for (int binCount = 0; ; ++binCount) {
                        if ((e = p.next) == null) {
                            p.next = newNode(hash, key, value, null);
                            if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                                treeifyBin(tab, hash);
                            break;
                        }
                        if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k))))
                            break;
                        p = e;
                    }
                }
                if (e != null) { // existing mapping for key
                    V oldValue = e.value;
                    if (!onlyIfAbsent || oldValue == null)
                        e.value = value;
                    afterNodeAccess(e);
                    return oldValue;
                }
            }
            ++modCount;
            if (++size > threshold)
                resize();
            afterNodeInsertion(evict);
            return null;
        }

    如果插入节点后整个map的size达到下次扩容的阙值,则进行扩容。主要看老的table和节点怎么拷贝到新的table上:
    通过下标找到桶上的节点,对老的table进行赋值null防止内存泄漏,
    1)如果单节点,则直接拷贝到新的桶上
    2)如果为红黑树节点,则对树进行分离。(每次扩容都是翻倍,与原来计算(n-1)&hash的结果相比,节点要么就在原来的位置,要么就被分配到“原位置+旧容量”这个位置。)
    3)如果为链表,则复制链表到新的table,同样会对节点重新hash后决定分配到原来的还是新的位置。
    resize源码如下:

      final Node<K,V>[] resize() {
            ... 省略 ...
            if (oldTab != null) {
                for (int j = 0; j < oldCap; ++j) {
                    Node<K,V> e;
                    if ((e = oldTab[j]) != null) {
                        oldTab[j] = null;
                        if (e.next == null)
                            newTab[e.hash & (newCap - 1)] = e;
                        else if (e instanceof TreeNode)
                            ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
                        else { // preserve order
                            Node<K,V> loHead = null, loTail = null;
                            Node<K,V> hiHead = null, hiTail = null;
                            Node<K,V> next;
                            do {
                                next = e.next;
                                if ((e.hash & oldCap) == 0) {
                                    if (loTail == null)
                                        loHead = e;
                                    else
                                        loTail.next = e;
                                    loTail = e;
                                }
                                else {
                                    if (hiTail == null)
                                        hiHead = e;
                                    else
                                        hiTail.next = e;
                                    hiTail = e;
                                }
                            } while ((e = next) != null);
                            if (loTail != null) {
                                loTail.next = null;
                                newTab[j] = loHead;
                            }
                            if (hiTail != null) {
                                hiTail.next = null;
                                newTab[j + oldCap] = hiHead;
                            }
                        }
                    }
                }
            }
            return newTab;
        }

    get

    通过hash值找到对应的桶。同样,get的时候判断桶是不是只有一个节点,而且key匹配上,是就直接返回这个节点了。不是则判断是红黑树还是链表,遍历节点找到key。
    getNode源码如下:

      final Node<K,V> getNode(int hash, Object key) {
            Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
            if ((tab = table) != null && (n = tab.length) > 0 &&
                (first = tab[(n - 1) & hash]) != null) {
                if (first.hash == hash && // always check first node
                    ((k = first.key) == key || (key != null && key.equals(k))))
                    return first;
                if ((e = first.next) != null) {
                    if (first instanceof TreeNode)
                        return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                    do {
                        if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k))))
                            return e;
                    } while ((e = e.next) != null);
                }
            }
            return null;
        }

    参考
    https://baike.baidu.com/item/%E7%BA%A2%E9%BB%91%E6%A0%91/2413209?fr=aladdin
    http://www.importnew.com/20386.html
    https://blog.csdn.net/panweiwei1994/article/details/77244920


    展开全文
  • 首先是让转化成一个排序的 ...然后只要再把中序遍历的数组转化为双向链表即可。 import java.util.*; public class Solution { public TreeNode Convert(TreeNode pRootOfTree) { if(pRootOfTree == null){ ...

    在这里插入图片描述
    首先是让转化成一个排序的
    给的是二叉搜索树,所以只需要将其中序遍历,得到的就是排序好的。
    然后只要再把中序遍历的数组转化为双向链表即可。

    import java.util.*;
    public class Solution {
        public TreeNode Convert(TreeNode pRootOfTree) {
            if(pRootOfTree == null){
                return pRootOfTree;
            }
            List<TreeNode> list = new ArrayList<>();
            mid(pRootOfTree,list);
            TreeNode head = list.get(0);
            TreeNode temp = head;
            head.left = null;
            for(int i=1;i<list.size();i++){
                temp.right=list.get(i);
                list.get(i).left = temp;
                temp = temp.right;
            }
            return head;
        }
        public void mid(TreeNode pRootOfTree,List<TreeNode> list){
            if(pRootOfTree==null){
                return;
            }
            mid(pRootOfTree.left,list);
            list.add(pRootOfTree);
            mid(pRootOfTree.right,list);
        }
    }
    
    展开全文
  • Java基础 - 集合框架

    2020-02-19 15:01:01
    treeset 实现排序 实现comparable接口。 HashMap: Java8前:数组+链表 通过hash(key.hashcode())%len计算要添加的元素存放的数组...TREEIFY_THRESHOLD 将链表转化成红黑树 将最坏性能从O(n)提升为O(logn) HashMap ...

    在这里插入图片描述
    treeset 实现排序 实现comparable接口。

    HashMap:

    Java8前:数组+链表
    通过hash(key.hashcode())%len计算要添加的元素存放的数组位置。
    如果总是分配到同一个桶中,则会性能恶化从O(1)变成O(n)
    Java8后:数组+链表+红黑树
    TREEIFY_THRESHOLD 将链表转化成红黑树 将最坏性能从O(n)提升为O(logn)

    HashMap put方法逻辑:

    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                       boolean evict) {
            Node<K,V>[] tab; Node<K,V> p; int n, i;
            if ((tab = table) == null || (n = tab.length) == 0)
                n = (tab = resize()).length;
            if ((p = tab[i = (n - 1) & hash]) == null)
                tab[i] = newNode(hash, key, value, null);
            else {
                Node<K,V> e; K k;
                if (p.hash == hash &&
                    ((k = p.key) == key || (key != null && key.equals(k))))
                    e = p;
                else if (p instanceof TreeNode)
                    e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
                else {
                    for (int binCount = 0; ; ++binCount) {
                        if ((e = p.next) == null) {
                            p.next = newNode(hash, key, value, null);
                            if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                                treeifyBin(tab, hash);
                            break;
                        }
                        if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k))))
                            break;
                        p = e;
                    }
                }
                if (e != null) { // existing mapping for key
                    V oldValue = e.value;
                    if (!onlyIfAbsent || oldValue == null)
                        e.value = value;
                    afterNodeAccess(e);
                    return oldValue;
                }
            }
            ++modCount;
            if (++size > threshold)
                resize();
            afterNodeInsertion(evict);
            return null;
        }
    
    1. 若HashMap未被初始化,则进行初始化操作
    2. 对Key求Hash值,依据Hash值计算下标
    3. 若未发生碰撞,则直接放入桶中
    4. 若发生碰撞,则以链表的方式链接到后面
    5. 若链表的长度超过阀值,且HashMap元素超过最低树化容量,则将链表转成红黑树
    6. 若链表的长度超过阀值,且HashMap元素没有超过最低树化容量,则直接进行resize
    7. 若节点已经存在,则用新值替换旧值
    8. 若桶满了(默认16*扩容因子0.75),就需要resize(扩容2倍重排)

    get方法逻辑

    final Node<K,V> getNode(int hash, Object key) {
            Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
            if ((tab = table) != null && (n = tab.length) > 0 &&
                (first = tab[(n - 1) & hash]) != null) {
                if (first.hash == hash && // always check first node
                    ((k = first.key) == key || (key != null && key.equals(k))))
                    return first;
                if ((e = first.next) != null) {
                    if (first instanceof TreeNode)
                        return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                    do {
                        if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k))))
                            return e;
                    } while ((e = e.next) != null);
                }
            }
            return null;
        }
    
    1. 通过key求hash值,依据hash值找到桶的位置
    2. 通过key.equals方法找到相应值 返回

    如何减少碰撞:

    • 扰动函数
    • 使用final对象,并采用合适的equals 和 hashcode方法;final不可变性能够缓存不同键的hashcode,使用String,Integer为key很适合。

    扩容问题:

    • 多线程环境,存在条件竞争
    • rehashing是一个耗时过程

    使hashmap线程安全方法:

    Map hashMap = new HashMap<>();
    Map safeHashMap = Collections.synchronizedMap(hashMap);
    

    synchronizedMap ,public方法使用mutex对象锁,再多线程环境下串行执行,效率低。

    HashTable

    • 线程安全:涉及到修改HashTable的方法,使用Synchronized修饰
    • 串行化方式运行,性能较差
    • 与hashmap类似

    ConccurentHashMap

    早期使用分段锁 Segment实现。将hashmap一个数组拆分多个数组并分别加锁。
    java8:CAS+synchronized 使锁细化。
    首先采用无锁操作CAS插入头节点,如果操作失败说明已经有其他线程插入头节点
    则循环重试。

    casTabAt(tab, i, null,new Node<K,V>(hash, key, value, null))
    

    若头节点已经存在,则尝试通过synchronized获取头节点的同步锁,在进行操作

    CAS
    CAS(Compare and Swap)乐观锁。只在提交操作时候检查是否违反数据完整性,提交失败则重试。
    一种高效实现线程安全性的方法。CAS操作失败时由开发者决定是继续尝试,还是执行其他操作。

    操作思想:
    包含三个操作数:内存位置(V-主内存值)/预期原值(A)/新值(B)
    当V与A相匹配,则V更新为B,否则处理器不做任何操作。

    put方法:

    final V putVal(K key, V value, boolean onlyIfAbsent) {
            if (key == null || value == null) throw new NullPointerException();
            int hash = spread(key.hashCode());
            int binCount = 0;
            for (Node<K,V>[] tab = table;;) {
                Node<K,V> f; int n, i, fh;
                if (tab == null || (n = tab.length) == 0)
                    tab = initTable();
                else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
                    if (casTabAt(tab, i, null,
                                 new Node<K,V>(hash, key, value, null)))
                        break;                   // no lock when adding to empty bin
                }
                else if ((fh = f.hash) == MOVED)
                    tab = helpTransfer(tab, f);
                else {
                    V oldVal = null;
                    synchronized (f) {
                        if (tabAt(tab, i) == f) {
                            if (fh >= 0) {
                                binCount = 1;
                                for (Node<K,V> e = f;; ++binCount) {
                                    K ek;
                                    if (e.hash == hash &&
                                        ((ek = e.key) == key ||
                                         (ek != null && key.equals(ek)))) {
                                        oldVal = e.val;
                                        if (!onlyIfAbsent)
                                            e.val = value;
                                        break;
                                    }
                                    Node<K,V> pred = e;
                                    if ((e = e.next) == null) {
                                        pred.next = new Node<K,V>(hash, key,
                                                                  value, null);
                                        break;
                                    }
                                }
                            }
                            else if (f instanceof TreeBin) {
                                Node<K,V> p;
                                binCount = 2;
                                if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                               value)) != null) {
                                    oldVal = p.val;
                                    if (!onlyIfAbsent)
                                        p.val = value;
                                }
                            }
                        }
                    }
                    if (binCount != 0) {
                        if (binCount >= TREEIFY_THRESHOLD)
                            treeifyBin(tab, i);
                        if (oldVal != null)
                            return oldVal;
                        break;
                    }
                }
            }
            addCount(1L, binCount);
            return null;
        }
    
    1. 判断Node数组是否初始化,没有则进行初始化

    2. 通过hash定位数组索引坐标,是否有Node节点,如果没有则使用通过CAS进行添加(链表头节点),添加失败则进入下一次循环。

    3. 检查到内部正在扩容,就帮助它一块扩容(helpTransfer(tab, f);)

    4. 否则使用synchronized锁住f元素(链表/红黑二叉树的头元素)
      如果是链表结构,则执行链表添加操作
      如果是树型结构,则执行树添加操作

    5. 判断链表长度已经达到临界点8(默认值TREEIFY_THRESHOLD)时,将链表转化为树结构 (treeifyBin(tab, i);)

    注意:
    size() 和 mappingCounting 方法区别,两者计算是否准确?
    多线程环境下如何控制扩容?

    HashMap/HashTable/ConccurentHashMap区别:

    1. hashmap线程不安全:数组+链表+红黑树
    2. hashtable线程安全:数组+链表。通过锁住整个hashtable来实现线程安全。效率低、
    3. ConccurentHashMap线程安全:数组+链表+红黑树。通过CAS+synchronized将锁细粒度到数组的每个元素来提升并发性能
    4. HashMap key 和value均可以为null。hashtable和concurrenthashmap不支持。
    展开全文
  • Java HashMap【笔记】

    2021-03-08 10:55:12
    其中当链表的长度大于等于 8 时,链表会转化成红黑树,当红黑树的大小小于等于 6 时,红黑树会转化成链表 类注释 1.允许 null 值,不同于 HashTable ,是线程不安全的 2.load factor 默认值是 0.75,是均衡了时间和...
  • 主要用于信息安全领域中的算法,把长度不同的信息转化为杂乱的128位的编码,找到一种数据内容与地址之间的映射关系。注意:不同的输入可能会散列相同的输出我们最熟悉的Object类中就提供了hashcode的方法。public ...
  • 当多个 key 的 hashcode 一致,但 key 值不同时,单个 Node 就会转化成链表,链表的查询复杂度是 O(n) 当链表的长度大于等于 8 并且数组的大小超过 64 时,链表就会转化成红黑树,红黑树的查询复杂度是 O(log(n)
  • 给定一个单链表,其中的元素按升序排序,请将它转化成平衡二叉搜索树(BST) 递归:o(nlogn) 解题思路: 1.找到链表的中点mid, 2.记录mid前缀,断开链表 3.将mid放入到树中 4.递归head(左链表),mid.next(右...
  • HashMap1.8以前(Entry数组+链表) loadfactor负载因子0.75 DEFAULT_INITIAL_CAPACITY 默认容量16 threshold容量*loadfactor put 先扩容再插入 如果定位到的数组位置没有元素 就直接插入。...64转化成红黑
  • Java面经3

    2019-09-03 23:11:57
    集合 1、Map和ConcurrentHashMap...数据结构:数组+链表(当链表长度到达8之后,会自动转化成红黑树)。 put:key的hash值,与hashMap的数组长度-1相与,得出的值即为需要存的数组的位置,然后通过尾插法插入链表中或...
  • 原因是当链表长度过长时会查询的时间复杂度时O(n),而转换红黑树后查询的时间复杂度为O(logn),提高了查询效率,那么什么时候由链表转化为红黑树呢? //树化阈值 static final int TREEIFY_THRESHOLD = 8; //树...
  • HashMap采用的是数组+链表+红黑树的形式。...(2)当链表中元素个数超过默认设定(8个),当数组的大小还未超过64的时候,此时进行数组的扩容,如果超过则将链表转化成红黑树。 什么时候链表转化为红
  • HashMap的底层是使用数组+链表/数组+红黑树,当链表长度大于阈值(默认为8)时,将链表转化为红黑树(将链表转换红黑树前会判断,如果当前数组的长度小于64时,娜美会先进行数组扩容,而不是转换为红黑树),以...
  • Java技术栈随笔

    2021-03-17 16:49:14
    得到),而在储存时,因运算后得到的下标可能重复,从而每个数组中储存的对象转化为储存链表,而链表中数量达到 8个时,及时转红黑树,提高map的效率 JVM的理解 Java虚拟机,是提供java运行的而构建的虚拟计算机...
  • 如图,数组 [11, 2, 5, 8, 6, 7, 2, 9, 4, 3, 1, 10], 转化成链表,快慢指针分别为 slow 和 fast, 起初指向第一个点 11。之后快指针每次走2步,慢指针每次走1步。假设在环中 x处相遇,慢指针肯定没走完一圈,快...
  • Java集合源码—HashMap

    2019-08-09 15:51:03
    当一个键的hash值与另一个键的hash值做运算后得到的在数组中位置相同, 这就说明出现了"哈希冲突", 所以采用链表, 将他们链一条链表. 当这个链表长度过长时, 就会将该链表转化为红黑树提高性能 而HashMap的内部...
  • hashMap原本是链表数组java8后,链表大小超过8的时候,会转化成红黑树,所以就有了TreeNode,它是间接继承HashMap.Node<K,V>的。数据包装在这两种结构中。最终数据的保存形式还是存放在transient Node<...
  • 在HashMap那篇文章讲过,在Java8中,HashMap是通过数组 + 链表 + 红黑树组织的,当链表中元素个数大于8时,会将链表转化成红黑树。而且Java API中TreeMap也是通过红黑树实现的,所以讲解红黑树,对于我们更好的了解...
  • 链表转化成红黑树条件 (链表长度为8,数组长度为64) Node节点的结构 Node节点的hash值由key在进行二次hashcode的值 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4NSUpF0e-...
  • java基础之HashMap

    2018-09-07 16:45:11
    本章环境java1.8 hashmap的几个默认初始值 ... TREEIFY_THRESHOLD 默认8,链表超过8就转化成红黑树 UNTREEIFY_THRESHOLD 默认6,链表数量少于6就会重新变成红黑树 MIN_TREEIFY_CAPACITY 默...
  • 在讲解HashMap之前,我们先说一说HashMap中...哈希表的关键是哈希化,就是将很大的哈希值转化成变成一定区间范围内的值,在上一章中我们采用了取余%操作来实现哈希化的。但是我们知道取余%是非常耗费性能的,尽量...
  • Map 集合

    2020-09-13 15:14:13
    HashMap是由数组链表组合构成的数据结构,Java8中链表长度超过8时会把长度超过8的链表转化成红黑树;存取时都会根据键值计算出”类别”(hashCode),再根据”类别”定位到数组中的位置并执行操作。单链表的头插入...
  • 08 HashMap 源码解析 自信和希望是青年的特权。 ...HashMap 源码很长,面试的问题也非常多,但这些面试问题,基本都是从源码中衍生出来的,所以我们只需要弄清楚...其中当链表的长度大于等于 8 时,链表转化成...
  • 一、Set集合 1.HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构。...在某个单向链表中的每一个节点上的hash值是相等的,hash值实际上是key调用hashCode方法,再通过"hash function"转化成的值。 ...
  • HashMap HashMap 是一个关联数组、哈希表,它是线程不安全的,允许key为null,...在JDK8中,当链表长度达到8,会转化成红黑树,以提升它的查询、插入效率,它实现了Map<K,V>, Cloneable, Serializable接口。 ...
  • 但是进入1.8之后,链表模式再一定情况下又会转换为红黑树在JDK8中,当链表长度达到8,并且hash桶容量超过64(MIN_TREEIFY_CAPACITY),会转化成红黑树,以提升它的查询、插入效率底层哈希桶的数据结构是数组,所以也会...
  • Java2实用教程.rar

    2014-11-10 10:33:17
    2 3Java数组 习题 第3章运算符 表达式和语句 3 1运算符与表达式 3 2语句概述 3 3控制语句 3 4 循环语句 3 5break和continue语句 习题 第4章类 对象和接口 4 1编程语言的几个发展阶段 4 1 1机器语言 4 1 2过程语言 ...
  • 1、Hash也叫散列、哈希。主要用于信息安全领域中的算法,把长度不同的信息转化为杂乱的128位的编码,找到一种数据内容与地址之间的映射关系。注意:不同的输入可能...数组:寻址容易,插入和删除困难链表正好相反。...
  • 1.8中,当链表长度到达8的时候,会转化成红黑树。 2.插入链表的方式 1.7是头插法,1.8是尾插法 3.扩容时,调整数据的方式 1.7其实就是根据hash值重新计算索引位置,然后将数据重新放到应该在的位置。 而1.8优化了...

空空如也

空空如也

1 2 3 4
收藏数 64
精华内容 25
关键字:

java数组转化成链表

java 订阅