📜  Java中的TreeMap put()方法(1)

📅  最后修改于: 2023-12-03 15:31:57.572000             🧑  作者: Mango

Java中的TreeMap put()方法

简介

TreeMap是Java中实现了SortedMap接口的一个集合类,TreeMap底层采用的是红黑树的数据结构。put()方法是TreeMap中向集合中添加元素的方法,本文将会介绍TreeMap put()方法的细节和使用方法。

语法格式

put()方法的函数原型为:

V put(K key, V value)

其中,K代表键,V代表值。该方法的意义是将键值对(key,value)存放到TreeMap中。如果TreeMap中已经存在该键,则使用新值替换旧值并返回旧值;如果TreeMap中不存在该键,则直接插入键值对并返回null。

示例

下面的示例展示了如何使用TreeMap put()方法进行添加和修改元素:

import java.util.TreeMap;

class Main {
  public static void main(String[] args) {
    TreeMap<String, Integer> treeMap = new TreeMap<>();

    // 向TreeMap中添加元素
    treeMap.put("apple", 1);
    treeMap.put("pear", 2);
    treeMap.put("banana", 3);

    System.out.println(treeMap); // 输出 {apple=1, banana=3, pear=2}

    // 修改TreeMap中的元素
    treeMap.put("pear", 4);

    System.out.println(treeMap); // 输出 {apple=1, banana=3, pear=4}
  }
}

输出:

{apple=1, banana=3, pear=2}
{apple=1, banana=3, pear=4}

接下来,本文将会详细讲解TreeMap put()方法的实现细节。

实现原理

TreeMap底层使用的数据结构是红黑树,Java的红黑树实现方式是基于Entry类,它是TreeMap的内部类。

每个Entry对象代表树中的一个节点,包括键值对(key,value)和指向左右子节点的指针(left,right)。TreeMap中维护了一个指向根节点的指针(root),它代表树的根节点。

对于每个节点,它的左子节点的键值比它小,右子节点的键值比它大。而且,对于每个节点,它的左右子树的高度相差不超过1,这也是红黑树的平衡性的体现。

下面是put()方法的实现流程:

  1. 检查传入的键值是否为null,如果是null则抛出NullPointerException异常;
  2. 检查树是否为空,如果是空的,则创建一个新的节点作为树的根节点;
  3. 将指针node指向根节点;
  4. 循环查找插入位置:
    1. 将查找过程中经过的节点的指针prev指向当前节点node;
    2. 如果插入的键小于当前节点的键,则将指针node指向当前节点的左子节点;
    3. 如果插入的键大于当前节点的键,则将指针node指向当前节点的右子节点;
    4. 如果插入的键等于当前节点的键,则将当前节点的值替换为新值,并返回旧值;
    5. 如果指针node为null,则代表已经找到了要插入的位置,跳出循环;
  5. 创建一个新的Entry对象,并将它的键值对设置为要插入的键值对;
  6. 如果要插入的键小于prev节点的键,则将新节点设置为prev节点的左子节点;否则将新节点设置为prev节点的右子节点;
  7. 新节点的父节点指针指向prev节点;
  8. 将新节点按红黑树的平衡性进行旋转和染色操作;
  9. 返回null。
红黑树的平衡性

红黑树是一种自平衡二叉搜索树,它能够保证在最坏情况下基本动态集合操作的时间复杂度为O(log n)。

在put()方法中,当新节点被插入后,红黑树可能会失去平衡。失去平衡的情况有以下两种:

  1. 新节点被插入到红色节点的左或者右子节点的左或者右子节点上;
  2. 新节点被插入到黑色节点的左或者右子节点的左和右子节点的右上。

为了保证红黑树的平衡性,需要进行旋转和染色两种操作。

旋转分为左旋和右旋:

  1. 左旋:将x节点旋转为左子节点,y节点旋转为右子节点。
        x                    y
  y           c        a         x
a   b      =>          =>    b   c
  1. 右旋:将y节点旋转为右子节点,x节点旋转为左子节点。
    y                     x
a       x       =>   y        c
      b   c        a    b    

染色分为红色和黑色:

  1. 红色节点:节点代表着红色节点,用于解决新增或删除节点时颜色不平衡,容易破坏红黑树平衡性的问题;
  2. 黑色节点:节点代表着黑色节点,在红黑树的染色问题中,黑色节点的平衡问题比较简单。

为了保证染色后的红黑树满足红黑树的五条性质,需要进行以下几种染色操作:

  1. 红节点染黑,黑节点染红;
  2. 红节点染黑,并将其父节点和爷爷节点染成红色;
  3. 红节点染黑,并将其兄弟节点和兄弟节点的子节点染成红色。
总结

TreeMap put()方法是向TreeMap中添加元素的方法,它的使用非常简单,只需要传入要添加的键值对即可。

底层实现原理是基于红黑树的数据结构,红黑树能够保证基本动态集合操作的时间复杂度为O(log n)。

当插入新节点后,TreeMap可能会失去平衡,为了保证红黑树的平衡性,需要进行旋转和染色操作,使得红黑树保持平衡。