热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

树实验报告

树-实验报告代码托管地址码云链接实验-1实现二叉树实验要求参考教材p375,完成链树LinkedBinaryTree的实现(getRight,contains,toS

树-实验报告

代码托管地址

  • 码云链接

实验-1实现二叉树


实验要求

参考教材p375,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试

实验步骤

get Right

  • 参考get Left方法把left改成right即可

public LinkedBinaryTree getRight() {if (root == null)throw new EmptyCollectionException ("Get left operation "+ "failed. The tree is empty.");LinkedBinaryTree result = new LinkedBinaryTree();result.root = root.getRight();return result;}

contains

  • 从意思上觉得和find方法相近,调用find方法,返回boolean类型

public boolean contains (int target) {BTNode node = null;if (root != null)node = root.find(target);if (node == null)return false;elsereturn true;}

preorderpostorder

  • 这里用到了迭代器和递归的思路,参考书中实现中序遍历的代码,改变一下左子树、根、右子树的顺序即可

public void inorder (ArrayIterator iter){//左根右if (left != null)left.inorder (iter);iter.add (element);if (right != null)right.inorder (iter);}public void preorder (ArrayIterator iter) {//根左右iter.add (element);if (left != null)left.preorder (iter);if (right != null)right.preorder (iter);}public void postorder (ArrayIterator iter) {//左右根if (left != null)left.postorder (iter);if (right != null)right.postorder (iter);iter.add (element);}

实验-2中序先序序列构造二叉树


实验要求

基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如教材P372,给出HDIBEMJNAFCKGL和ABDHIEJMNCFGKL,构造出附图中的树

1062634-20171029152610789-899648489.jpg

实验思路

参考实现二叉树(链式存储结构)http://www.jb51.net/article/88460.htm)

测试结果

1062634-20171029202350945-1942902336.png

实验-3决策树


实验要求

完成PP16.6,利用决策树来完成20问yes or no的游戏

实验知识点

  • 一棵决策树包含一个根结点、若干个内部结点和若干个叶结点。叶结点对应于决策结果,其他每个结点则对应于一个属性测试。
  • 在理顺左右子树和根节点对应关系的前提下,修改BackPainExpert中的问题并写一个简单的驱动测试

测试结果

1062634-20171029203813789-1511070017.png

实验-4表达式树


实验要求

完成PP16.8,使用二叉树表示表达式树

实验思路

  • 参考利用Java实现表达式二叉树

实验代码

原本的Node与已有的BTNode功能相近,就改用了现成的。

package EXP2;
import ch16.javafoundations.BTNode;import java.util.ArrayList;/*** Created by jxy6996 on 2017/10/26.*/
public class Formaluetree {private String s&#61;"";private BTNode root; //根节点/*** 创建表达式二叉树* &#64;param str 表达式*/public void creatTree(String str){//声明一个数组列表&#xff0c;存放的操作符&#xff0c;加减乘除ArrayList operList &#61; new ArrayList();//声明一个数组列表&#xff0c;存放节点的数据ArrayList numList &#61; new ArrayList();//第一&#xff0c;辨析出操作符与数据&#xff0c;存放在相应的列表中for(int i&#61;0;i&#61;&#39;0&#39;&&ch<&#61;&#39;9&#39;){s&#43;&#61;ch;}else{numList.add(new BTNode(s));s&#61;"";operList.add(ch&#43;"");}}//把最后的数字加入到数字节点中numList.add(new BTNode(s));while(operList.size()>0){ //第三步&#xff0c;重复第二步&#xff0c;直到操作符取完为止//第二&#xff0c;取出前两个数字和一个操作符&#xff0c;组成一个新的数字节点BTNode left &#61; numList.remove(0);BTNode right &#61; numList.remove(0);String oper &#61; operList.remove(0);BTNode node &#61; new BTNode(oper);node.setLeft(left);node.setRight(right);numList.add(0,node); //将新生的节点作为第一个节点&#xff0c;同时以前index&#61;0的节点变为index&#61;1}//第四步&#xff0c;让根节点等于最后一个节点root &#61; numList.get(0);}/*** 输出结点数据*/public void output(){output(root); //从根节点开始遍历}/*** 输出结点数据* &#64;param node*/public void output(BTNode node){if(node.getLeft()!&#61;null){ //如果是叶子节点就会终止output(node.getLeft());}System.out.print(node.getElement()); //遍历包括先序遍历&#xff08;根左右&#xff09;、中序遍历&#xff08;左根右&#xff09;、后序遍历&#xff08;左右根&#xff09;if(node.getRight()!&#61;null){output(node.getRight());}}public static void main(String[] args) {Formaluetree tree &#61; new Formaluetree();tree.creatTree("45&#43;23*56/2-5");//创建表达式的二叉树tree.output();//输出验证}
}

实验问题与解决措施

  • 原代码中有一行用到了BTNode里没有的方法
    1062634-20171029205916695-1275088385.jpg

  • 解决措施如下&#xff1a;

BTNode node &#61; new BTNode(oper);
node.setLeft(left);
node.setRight(right);

测试结果

1062634-20171029210147570-1048433503.png

实验-5二叉查找树


实验要求

完成PP17.1&#xff0c;完成LinkedBinarySearchTree类的实现&#xff0c;特别是findMax和findMin两个操作

实验思路

  • 对一棵二叉排序树采用中序遍历进行输出的数据一定是递增序列&#xff0c;所以调用inorder()方法

public T findMin() {ArrayIterator iter &#61; (ArrayIterator)inorder();return iter.get(0);}public T findMax() {ArrayIterator iter &#61; (ArrayIterator)inorder();return iter.get(iter.size()-1);}

测试结果

1062634-20171029211515148-780258154.png

实验-6红黑树分析


实验要求

参考http://www.cnblogs.com/rocedu/p/7483915.html对Java中的红黑树&#xff08;TreeMap&#xff0c;HashMap&#xff09;进行源码分析

实验知识点

  • 参考(通过分析JDK 源代码研究 TreeMap 红黑树算法实现)[http://www.cnblogs.com/abc8023/p/4339021.html#D]

红黑树

1062634-20171029221312164-424110985.png

  • 备注&#xff1a;白色代表红色。

  • 排序二叉树虽然可以快速检索&#xff0c;但在最坏的情况下&#xff1a;如果插入的节点集本身就是有序的&#xff0c;要么是由小到大排列&#xff0c;要么是由大到小排列&#xff0c;那么最后得到的排序二叉树将变成链表&#xff1a;所有节点只有左节点&#xff08;如果插入节点集本身是大到小排列&#xff09;&#xff1b;或所有节点只有右节点&#xff08;如果插入节点集本身是小到大排列&#xff09;。在这种情况下&#xff0c;排序二叉树就变成了普通链表&#xff0c;其检索效率就会很差。

  • 为了改变排序二叉树存在的不足&#xff0c;Rudolf Bayer 与 1972 年发明了另一种改进后的排序二叉树&#xff1a;红黑树&#xff0c;他将这种排序二叉树称为“对称二叉 B 树”&#xff0c;而红黑树这个名字则由 Leo J. Guibas 和 Robert Sedgewick 于 1978 年首次提出。

  • 红黑树是一个更高效的检索二叉树&#xff0c;因此常常用来实现关联数组。典型地&#xff0c;JDK 提供的集合类 TreeMap 本身就是一个红黑树的实现。

  • 红黑树在原有的排序二叉树增加了如下几个要求&#xff1a;

Java 实现的红黑树

  • 性质 1&#xff1a;每个节点要么是红色&#xff0c;要么是黑色。
  • 性质 2&#xff1a;根节点永远是黑色的。
  • 性质 3&#xff1a;所有的叶节点都是空节点&#xff08;即 null&#xff09;&#xff0c;并且是黑色的。
  • 性质 4&#xff1a;每个红色节点的两个子节点都是黑色。&#xff08;从每个叶子到根的路径上不会有两个连续的红色节点&#xff09;
  • 性质 5&#xff1a;从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点。

性质 3 中指定红黑树的每个叶子节点都是空节点&#xff0c;而且并叶子节点都是黑色。但 Java 实现的红黑树将使用 null 来代表空节点&#xff0c;因此遍历红黑树时将看不到
黑色的叶子节&#xff0c;看到每个叶子节点都是红色的。
性质 4 则保证了从根节点到叶子节点的最长路径的长度不会超过任何其他路径的两倍。假如有一棵黑色高度为 3 的红黑树&#xff1a;从根节点到叶节点的最短路径长度是 2&#xff0c;该路径上全是黑色节点&#xff08;黑节点 - 黑节点 - 黑节点&#xff09;。最长路径也只可能为 4&#xff0c;在每个黑色节点之间插入一个红色节点&#xff08;黑节点 - 红节点 - 黑节点 - 红节点 - 黑节点&#xff09;&#xff0c;性质 4 保证绝不可能插入更多的红色节点。由此可见&#xff0c;红黑树中最长路径就是一条红黑交替的路径。
性质 5中表示红黑树从根节点到每个叶子节点的路径都包含相同数量的黑色节点&#xff0c;因此从根节点到叶子节点的路径中包含的黑色节点数被称为树的“黑色高度&#xff08;black-height&#xff09;”。

1.什么是Map&#xff1f;

  • 在数组中我们是通过数组下标来对其内容索引的&#xff0c;而在Map中我们通过对象来对对象进行索引&#xff0c;用来索引的对象叫做key&#xff0c;其对应的对象叫做value。这就是我们平时说的键值对。

  • HashMap通过hashcode对其内容进行快速查找&#xff0c;而 TreeMap中所有的元素都保持着某种固定的顺序&#xff0c;如果你需要得到一个有序的结果你就应该使用TreeMap&#xff08;HashMap中元素的排列顺序是不固定的&#xff09;。
  • 2.两种常规Map实现
  • HashMap&#xff1a;基于哈希表实现。使用HashMap要求添加的键类明确定义了hashCode()和equals()[可以重写hashCode()和equals()]&#xff0c;为了优化HashMap空间的使用&#xff0c;您可以调优初始容量和负载因子。
  • (1)HashMap(): 构建一个空的哈希映像
    (2)HashMap(Map m): 构建一个哈希映像&#xff0c;并且添加映像m的所有映射
    (3)HashMap(int initialCapacity): 构建一个拥有特定容量的空的哈希映像
    (4)HashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的哈希映像

  • TreeMap&#xff1a;基于红黑树实现。TreeMap没有调优选项&#xff0c;因为该树总处于平衡状态。
  • (1)TreeMap():构建一个空的映像树
    (2)TreeMap(Map m): 构建一个映像树&#xff0c;并且添加映像m中所有元素
    (3)TreeMap(Comparator c): 构建一个映像树&#xff0c;并且使用特定的比较器对关键字进行排序
    (4)TreeMap(SortedMap s): 构建一个映像树&#xff0c;添加映像树s中所有映射&#xff0c;并且使用与有序映像s相同的比较器排序

3.两种常规Map性能

HashMap&#xff1a;适用于在Map中插入、删除和定位元素。
Treemap&#xff1a;适用于按自然顺序或自定义顺序遍历键(key)。

4.比较

HashMap通常比TreeMap快一点(树和哈希表的数据结构使然)&#xff0c;建议多使用HashMap&#xff0c;在需要排序的Map时候才用TreeMap。

TreeMap

  • [1] TreeMap的底层使用了红黑树来实现&#xff0c;像TreeMap对象中放入一个key-value 键值对时&#xff0c;就会生成一个Entry对象&#xff0c;这个对象就是红黑树的一个节点&#xff0c;其实这个和HashMap是一样的&#xff0c;一个Entry对象作为一个节点&#xff0c;只是这些节点存放的方式不同。
  • [2] 存放每一个Entry对象时都会按照key键的大小按照二叉树的规范进行存放&#xff0c;所以TreeMap中的数据是按照key从小到大排序的。

TreeMap类源码&#xff1a;

public class TreeMap extends AbstractMap implements NavigableMap, Cloneable, java.io.Serializable
{ /** * The comparator used to maintain order in this tree map, or * null if it uses the natural ordering of its keys. * * &#64;serial */ private final Comparator comparator; // 根节点 private transient Entry root &#61; null; /** * The number of entries in the tree * 树中的节点数&#xff0c;即entry对象的个数 */ private transient int size &#61; 0; /** * The number of structural modifications to the tree. * 树修改的次数 */ private transient int modCount &#61; 0;

TreeMap的内部类Entry即一个节点&#xff1a;

static final class Entry implements Map.Entry { // 关键字key 按照key的哈希值来存放 K key; // key对应的value值 V value; // 左节点 Entry left &#61; null; // 右节点 Entry right &#61; null; // 父节点 Entry parent; boolean color &#61; BLACK; /** * Make a new cell with given key, value, and parent, and with * {&#64;code null} child links, and BLACK color. */ Entry(K key, V value, Entry parent) { this.key &#61; key; this.value &#61; value; this.parent &#61; parent; } /** * Returns the key. * * &#64;return the key */ public K getKey() { return key; } /** * Returns the value associated with the key. * * &#64;return the value associated with the key */ public V getValue() { return value; } /** * Replaces the value currently associated with the key with the given * value. * * &#64;return the value associated with the key before this method was * called */ public V setValue(V value) { V oldValue &#61; this.value; this.value &#61; value; return oldValue; } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry e &#61; (Map.Entry)o; return valEquals(key,e.getKey()) && valEquals(value,e.getValue()); } }

put(K key,V value) 添加方法添加一个节点&#xff1a;

public V put(K key, V value) { Entry t &#61; root; //判断根节点是否存在&#xff0c;如果不存在 if (t &#61;&#61; null) { compare(key, key); // type (and possibly null) check // 将新的key-value对创建一个Entry&#xff0c;并将该Entry作为root root &#61; new Entry<>(key, value, null); // 计算节点数 size &#61; 1; modCount&#43;&#43;; return null; } int cmp; Entry parent; // split comparator and comparable paths // 如果有根节点则&#xff0c;添加的key和root节点的key进行比较&#xff0c;判断是做左节点、右节点 Comparator cpr &#61; comparator; // 如果比较器cpr不为null&#xff0c;即表明采用定制排序方式 if (cpr !&#61; null) { //比较算法的开始&#xff0c;这里完成了比较和存储 do { // 使用parent暂存上次循环后的t所对应的Entry&#xff0c;如果是首次则是root节点。 parent &#61; t; // 新插入的key和当前节点&#xff08;首次是root节点&#xff09;t的key进行比较 cmp &#61; cpr.compare(key, t.key); // 如果新插入的key的值小于t的key值,那么t&#61;t.left即再用当前节点的左节点进行比较 if (cmp <0) t &#61; t.left; // 如果新插入的key的值大于t的key的值,那么t等于t的右节点即在用当前节点的右节点进行比较 else if (cmp > 0) t &#61; t.right; else // 如果两个key的值相等&#xff0c;那么新的value覆盖原有的value&#xff0c;并返回原有的value return t.setValue(value); //如果t节点的左节点、右节点不为空则继续循环&#xff01;知道null为止&#xff0c;这样也就找到了新添加key的parent节点。 } while (t !&#61; null); } else { if (key &#61;&#61; null) throw new NullPointerException(); Comparable k &#61; (Comparable) key; do { // 使用parent上次循环后的t所引用的Entry parent &#61; t; // 拿新插入的key和t的key进行比较 cmp &#61; k.compareTo(t.key); // 如果新插入的key小于t的key&#xff0c;那么t等于t的左节点 if (cmp <0) t &#61; t.left; // 如果新插入的key大于t的key&#xff0c;那么t等于t的右节点 else if (cmp > 0) t &#61; t.right; else // 如果两个key相等&#xff0c;那么新的value覆盖原有的value&#xff0c;并返回原有的value return t.setValue(value); } while (t !&#61; null); } //新创建一个节点即put进来的key value Entry e &#61; new Entry<>(key, value, parent); // 如果新插入的key的值小于parent的key的值 则e作为parent的左子节点 if (cmp <0) parent.left &#61; e; // 如果新插入的key的值大于parent的key的值 则e作为parent的右子节点 else parent.right &#61; e; // 修复红黑树 fixAfterInsertion(e); size&#43;&#43;; modCount&#43;&#43;; return null; }

  • 注意&#xff1a;这里没说红黑树只是说了二叉树的查找&#xff0c;其实TreeMap是使用红黑树的&#xff0c;所以有个fixAfterInsertion(e)方法&#xff08;如下&#xff09;就是保持红黑树的方法。参考TreeMap红黑树算法实现

// 插入节点后修复红黑树private void fixAfterInsertion(Entry x) { x.color &#61; RED; // 直到 x 节点的父节点不是根&#xff0c;且 x 的父节点不是红色while (x !&#61; null && x !&#61; root && x.parent.color &#61;&#61; RED) { // 如果 x 的父节点是其父节点的左子节点if (parentOf(x) &#61;&#61; leftOf(parentOf(parentOf(x)))) { // 获取 x 的父节点的兄弟节点Entry y &#61; rightOf(parentOf(parentOf(x))); // 如果 x 的父节点的兄弟节点是红色if (colorOf(y) &#61;&#61; RED) { // 将 x 的父节点设为黑色setColor(parentOf(x), BLACK); // 将 x 的父节点的兄弟节点设为黑色setColor(y, BLACK); // 将 x 的父节点的父节点设为红色setColor(parentOf(parentOf(x)), RED); x &#61; parentOf(parentOf(x)); } // 如果 x 的父节点的兄弟节点是黑色else{ // 如果 x 是其父节点的右子节点if (x &#61;&#61; rightOf(parentOf(x))) { // 将 x 的父节点设为 x x &#61; parentOf(x); rotateLeft(x); } // 把 x 的父节点设为黑色setColor(parentOf(x), BLACK); // 把 x 的父节点的父节点设为红色setColor(parentOf(parentOf(x)), RED); rotateRight(parentOf(parentOf(x))); } } // 如果 x 的父节点是其父节点的右子节点else{ // 获取 x 的父节点的兄弟节点Entry y &#61; leftOf(parentOf(parentOf(x))); // 如果 x 的父节点的兄弟节点是红色if (colorOf(y) &#61;&#61; RED) { // 将 x 的父节点设为黑色。setColor(parentOf(x), BLACK); // 将 x 的父节点的兄弟节点设为黑色setColor(y, BLACK); // 将 x 的父节点的父节点设为红色setColor(parentOf(parentOf(x)), RED); // 将 x 设为 x 的父节点的节点x &#61; parentOf(parentOf(x)); } // 如果 x 的父节点的兄弟节点是黑色else{ // 如果 x 是其父节点的左子节点if (x &#61;&#61; leftOf(parentOf(x))) { // 将 x 的父节点设为 x x &#61; parentOf(x); rotateRight(x); } // 把 x 的父节点设为黑色setColor(parentOf(x), BLACK); // 把 x 的父节点的父节点设为红色setColor(parentOf(parentOf(x)), RED); rotateLeft(parentOf(parentOf(x))); } } } // 将根节点设为黑色root.color &#61; BLACK; }

HashMap

HashMap类源码&#xff1a;

public class HashMapextends AbstractMap implements Map, Cloneable, Serializable
{ /** * The default initial capacity - MUST be a power of two. * 默认的容量必须为2的幂 */ static final int DEFAULT_INITIAL_CAPACITY &#61; 16; /** * The maximum capacity, used if a higher value is implicitly specified * by either of the constructors with arguments. * MUST be a power of two <&#61; 1<<30. *默认最大值 */ static final int MAXIMUM_CAPACITY &#61; 1 <<30; /** * The load factor used when none specified in constructor. * 负载因子 */ static final float DEFAULT_LOAD_FACTOR &#61; 0.75f; /** * The table, resized as necessary. Length MUST Always be a power of two. * 到这里就发现了&#xff0c;HashMap就是一个Entry[]类型的数组了。 */ transient Entry[] table;

HashMap类构造函数源码&#xff1a;

/** * Constructs an empty HashMap with the specified initial * capacity and load factor. * &#64;param initialCapacity the initial capacity * &#64;param loadFactor the load factor * &#64;throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ // 初始容量&#xff08;必须是2的n次幂&#xff09;&#xff0c;负载因子 public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity <0) throw new IllegalArgumentException("Illegal initial capacity: " &#43; initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity &#61; MAXIMUM_CAPACITY; if (loadFactor <&#61; 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " &#43; loadFactor); // Find a power of 2 >&#61; initialCapacity int capacity &#61; 1; // 获取最小于initialCapacity的最大值&#xff0c;这个值是2的n次幂&#xff0c;所以我们定义初始容量的时候尽量写2的幂 while (capacity &#61; Holder.ALTERNATIVE_HASHING_THRESHOLD);
init(); }

HashMap--put&#xff1a;

  • 疑问思考&#xff1a;如果两个key通过hash%Entry[].length得到的index相同&#xff0c;会不会有覆盖的危险&#xff1f;
  • 这里HashMap里面用到链式数据结构的一个概念。上面提到过Entry类里面有一个next属性&#xff0c;作用是指向下一个Entry。打个比方&#xff0c; 第一个键值对A进来&#xff0c;通过计算其key的hash得到的index&#61;0&#xff0c;记做:Entry[0] &#61; A。一会后又进来一个键值对B&#xff0c;通过计算其index也等于0&#xff0c;现在怎么办&#xff1f;HashMap会这样做:B.next &#61; A,Entry[0] &#61; B,如果又进来C,index也等于0,那么C.next &#61; B,Entry[0] &#61; C&#xff1b;这样我们发现index&#61;0的地方其实存取了A,B,C三个键值对,他们通过next这个属性链接在一起。所以疑问不用担心。也就是说数组(桶)中存储的是最后插入的元素。如果hash%Entry[].length得到的index相同而且key.equals(keyother) 也相同&#xff0c;则这个Key对应的value会被替换成新值。

Put方法&#xff1a;

public V put(K key, V value) { //key为null的entry总是放在数组的头节点上,也就是上面说的"桶"中 if (key &#61;&#61; null) return putForNullKey(value); // 获取key的哈希值 int hash &#61; hash(key); // 通过key的哈希值和table的长度取模确定‘桶’&#xff08;bucket&#xff09;的位置 int i &#61; indexFor(hash, table.length); for (Entry e &#61; table[i]; e !&#61; null; e &#61; e.next) { Object k; //如果key映射的entry在链表中已存在&#xff0c;则entry的value替换为新value if (e.hash &#61;&#61; hash && ((k &#61; e.key) &#61;&#61; key || key.equals(k))) { V oldValue &#61; e.value; e.value &#61; value; e.recordAccess(this); return oldValue; } } modCount&#43;&#43;; addEntry(hash, key, value, i); return null; }

小结&#xff1a;

1、HashMap 是链式数组&#xff08;存储链表的数组&#xff09;实现查询速度可以&#xff0c;而且能快速的获取key对应的value。

2、查询速度的影响因素有容量和负载因子&#xff0c;容量大负载因子小查询速度快但浪费空间&#xff0c;反之则相反。

3、数组的index值是&#xff08;key 关键字&#xff0c; hashcode为key的哈希值&#xff0c; len 数组的大小&#xff09;&#xff1a;hashcode%len的值来确定&#xff0c;如果容量大负载因子小则index相同&#xff08;index相同也就是指向了同一个桶&#xff09;的概率小&#xff0c;链表长度小则查询速度快&#xff0c;反之index相同的概率大链表比较长查询速度慢。

4、对于HashMap以及其子类来说&#xff0c;他们是采用hash算法来决定集合中元素的存储位置&#xff0c;当初始化HashMap的时候系统会创建一个长度为capacity的Entry数组&#xff0c;这个数组里可以存储元素的位置称为桶&#xff08;bucket&#xff09;,每一个桶都有其指定索引&#xff0c;系统可以根据索引快速访问该桶中存储的元素。

5、无论何时HashMap 中的每个桶都只存储一个元素&#xff08;Entry 对象&#xff09;。由于Entry对象可以包含一个引用变量用于指向下一个Entry&#xff0c;因此可能出现HashMap的桶&#xff08;bucket&#xff09;中只有一个Entry,但这个Entry指向另一个Entry 这样就形成了一个Entry 链。

6、通过上面的源码发现HashMap在底层将key_value对当成一个整体进行处理&#xff08;Entry 对象&#xff09;这个整体就是一个Entry对象&#xff0c;当系统决定存储HashMap中的key_value对时&#xff0c;完全没有考虑Entry中的value&#xff0c;而仅仅是根据key的hash值来决定每个Entry的存储位置。

参考HashMap、HashTable、TreeMap 深入分析及源码解析

实验总结

  • 实验过程中遇到问题要及时记录;实验难度大&#xff0c;要参考很多资料。

转:https://www.cnblogs.com/JXY6996/p/7742197.html



推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 判断数组是否全为0_连续子数组的最大和的解题思路及代码方法一_动态规划
    本文介绍了判断数组是否全为0以及求解连续子数组的最大和的解题思路及代码方法一,即动态规划。通过动态规划的方法,可以找出连续子数组的最大和,具体思路是尽量选择正数的部分,遇到负数则不选择进去,遇到正数则保留并继续考察。本文给出了状态定义和状态转移方程,并提供了具体的代码实现。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
author-avatar
body胤ly_680
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有