一. Map集合
Map就是一个集合,是一个键值对。
1.1 HashMap
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { //初始化容量 数组的长度是16 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 16 //最大容量 最多能保存多少个键值对 static final int MAXIMUM_CAPACITY = 1 << 30; //加载因子 扩容的时机 16 第一个已经存放了12个值就库容 扩容为原来2倍 static final float DEFAULT_LOAD_FACTOR = 0.75f; //树化的阈值 当一个节点上的元素个数达到8时,链表就转化红黑树 static final int TREEIFY_THRESHOLD = 8; //反树化的阈值 当删除元素时,从红黑树重写转化为链表 的临界值 static final int UNTREEIFY_THRESHOLD = 6; //树化的最小容量 数组中所有元素的和达到64,也会进行树形 static final int MIN_TREEIFY_CAPACITY = 64; //链表的数组 HashMap的底层的主结构就是链表的数组 transient Node<K,V>[] table; //键值对的个数 transient int size; //链表 单项链表 static class Node<K,V> implements Map.Entry<K,V> { final int hash; // key的hash值,用来计算Node的存放位置 final K key; V value; Node<K,V> next; //单向链表 Node(int hash, K key, V value, Node<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } } //红黑树 static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> { TreeNode<K,V> parent; // red-black tree links TreeNode<K,V> left; TreeNode<K,V> right; TreeNode<K,V> prev; // needed to unlink next upon deletion boolean red; TreeNode(int hash, K key, V val, Node<K,V> next) { super(hash, key, val, next); } } }
-
首先会创建一个长度为16的Node类型的数组
-
当添加键值对时,会获取key的hash值,创建一个Node对象
-
在创建的Node对象中保存 hash key value next=null
-
-
我们根据key的hash值计算出该Node对象在数组中存储的位置
-
判断该位置有没有元素,如果没有存对象,就直接放进去
-
如果该位置已经有元素,那么就依次和已经存放的Node对象比较Hash值是否相等
-
如果没有相等的,那就直接添加链表尾部
-
如果有hash值相等的,那就进行key的equals方法的比较
-
如果equals结果为true,那么就进行value值得替换,不再追加Node
-
equals结果为false,那就把当前Node追加在尾部
-
-
-
-
如果当前Node数组中已经有 长度*75%的位置已经保存的元素,那么就进行扩容,扩容后的长度为现在长度的两倍。
-
如果数组中一个下标的位置中保存的链表长度已经达到8个,那么链表的数据结构就会转化为红黑树(就是为查询的速度)
1.2 Hashtable
Hashtable也是Map的一个实现类,它是线程安全的
1.3 TreeMap
TreeMap对Key进行排序
二. HashSet
底层是HashMap,我们在使用HashSet保存值时,保存就是一个一个的键值对,保存的值作为键值对的键
所以如果判断Set中的两个对象是重复的
-
比较hash值 相等
-
进行equals()判断 true
如果让两个对象的hash值相等,equals比较结果为true,可以通过重写hashCode和equals方法,选择在什么情况下两个对象相等。
package com.qfedu; import java.util.HashSet; import java.util.Set; public class Demo02 { public static void main(String[] args) { /* * set无序不可重复的集合 * 如果出现添加重复的元素,则添加不成功 * * Map的key不能重复,如果出现重复,value会覆盖 */ Set<Student> set = new HashSet<Student>(); Student s1 = new Student("jackma", 17, "男", "123"); Student s2 = new Student("pony", 13, "男", "234"); Student s3 = new Student("tomlei", 12, "男", "345"); Student s4 = new Student("robin", 16, "男", "456"); Student s5 = new Student("jackma22", 17, "男", "123"); set.add(s1); set.add(s2); set.add(s3); set.add(s4); set.add(s5); for(Student s : set) { System.out.println(s); } } } class Student { // 姓名,年龄,性别 身份证号码 //创建一个set集合保存学生信息,如果两个学生身份证号码相同,则认为是同一个学生 private String name; private Integer age; private String gender; private String cardNo; public Student() { } public Student(String name, Integer age, String gender, String cardNo) { super(); this.name = name; this.age = age; this.gender = gender; this.cardNo = cardNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getCardNo() { return cardNo; } public void setCardNo(String cardNo) { this.cardNo = cardNo; } /* * 在现实中,如果两个人的身份证号码相同,那么这两个人就是同一个人 * 在程序中,就是两个对象相等 * * 需要重写hashCode equals 方法 * - 两个对象的hashCode相等 * - 两个对象比较结果为true */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((cardNo == null) ? 0 : cardNo.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (cardNo == null) { if (other.cardNo != null) return false; } else if (!cardNo.equals(other.cardNo)) return false; return true; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", gender=" + gender + ", cardNo=" + cardNo + "]"; } }