概述
/**
-
Map集合的特点:key部分无序(插入的顺序和取出的顺序不一致),key不可重复,
-
Map集合实现类有三个:HashMap,Hashtable TreeMap三个实现集合
-
Map集合存放的元素都是以键值对的方式存储的,这种方式模仿了数组的方式,可以把key部分当做一个下标,但是下标有不仅仅局限于整数,扩大了范围
-
迭代器只是Collection集合里面特有的,和Map集合无关,Map集合的遍历方式有所不同,由于使用了key,模仿数组的下标,因此可以对下标的操作遍历集合
-
增强for循环的方式遍集合,获取所有的key 元素,变成一个Set集合来遍历集合,获取所有的Value成一个Collection的集合遍历集合,通过一个entrySet方法
-
获取一个泛型Map.Entry类型的Set集合的元素,通过该类型的元素来获取key和value,
-
-
HashMap:存入这个元素的key部分必须重写equals方法和hashCode方法,hashCode方法保证了分布的均匀性,eqauls方法保证了key部分不会重复
-
HashMap默认的大小是16,默认的加载因子是0.75,超过这个因子就会扩容,每次扩容到自身的2倍,在往哈希表里面存储的时候每次先执行的是hashCode算法
-
确定数组的下标之后再执行的是equals算法,如果没有equals算法,就会重复,
-
-
HashMap集合中put方法的实现原理
-
: 第一步:先将k,v封装到Node对象当中去
-
第二步:底层调用k的hashCode方法,得到hash值
-
第三步:然后底层调用哈希算法将hash值变成数组的下标
-
第四步:如果下标位置没有元素,就添加一个元素,如果下标的位置有链表
-
就用k和链表上每一个k作比较,如果所有的equals方法返回的都是false就在
-
链表的末尾添加上去,如果有一个k的equals方法返回了true,就把这个节点给
-
的value内容给覆盖了,这样保证了k的唯一性
-
HashMap集合当中的get方法的实现原理:
-
第一步:用k的hashCode方法得到hash值,然后用哈希算法得到数组的下标
-
通过数组的下标快速度定位到相应的链表上,如果这个位置什么都没有,就返回null
-
如果有,就用这个k和单项链表的k作比较,如果全部的equals方法都返回false
-
结果就返回null如果有一个节点的equals方法返回了true就把这个节点的
-
value返回
-
、
-
Node节点:一个Node节点有四个值,
-
hash:同一个单项链表上面的hash值是一样的
-
value:内容
-
key:key值
-
next:Node的类型的值,指向下一个Node的内存地址,构成单向链表的关键,因为只有一个next所以,构成的链表是一定是单向的
-
-
-
HashMap的使用:
-
我们在存和取的时候,一定要重写hashCode和equals方法,
-
如果hashCod方法返回固定的值,那么HashMap就只是一个单向链表
-
不能充分发挥出HashMap结构的功能性和效率
-
-
-
-
hashCode方法的重写:
-
在HashMap里面我们必须要对HashCode进行重写,以保证其在分布的时候,分布在均匀的链表上,
-
在HashSet里面。我们也要对其进行重写因为,HashSet是放在HashMap里面的Key部分的,我们也要保证分布均匀
-
equals方法的重写:
-
在HashMap里面,我们要进行equals方法的重写,比较的应该是内容,而不是内存地址,以保证key的唯一性
-
在HashSet里面,我们也要进行equals方法的重写,以保证内容的唯一性
-
-
-
HashMap的初始化容量是16,并且要求容量每一次都必须是2的幂次, 这是为了分布均与,HashMap的容量因子是0.75,指的是,当数组使用率达到百分之75的时候就开始扩容
-
-
-
终结结论:放在HashSet里面的元素和放在HashMap key里面的元素,一定要一块重写equals方法和hashCode方法,直接用IDEA自动生成
-
在JDK8之后,在HashMap里面如果元素的个数超过8个单向链表就会自动变成红黑树的数据结构,如果红黑树的元素小于6时,会自动变成单向链表
-
在扩容的时候,变成原来容量的二倍,允许null值的存入,不论是key还是value
-
但是HashTablea是key和value都不能空不能null,否者直接空指针异常Hashtable初始化容量是11,因子也是0.75,不是二的幂次和HashMap的算法不一样
-
每一次的扩容是自己的二倍+1
-
Properties properties=new Properties();这个properties是继承Hashtable的一个类,这个类只能往里面存取字符串,目前需要掌握的有两个方法
-
setProperties() 和方法getProperties()这两个方法,用来存取数据
*/
public class MapTest {
public static void main(String[] args) {HashMap<Integer, String> hashMap = new HashMap<>(); hashMap.put(0, "第一个元素"); hashMap.put(1, "第2个元素"); hashMap.put(2, "第3个元素"); hashMap.put(3, "第4个元素");
//这里我们通过获取key部分然后获取他的迭代器通过迭代器获通过get方法获取他的value值
Set keySet = hashMap.keySet();
Iterator iterator = keySet.iterator();
while (iterator.hasNext()) {
System.out.println(hashMap.get(iterator.next()));
}
//这里通过直接通过get来获取他的value
for (int i = 0; i < hashMap.size(); i++) {
System.out.println(hashMap.get(i));
}
//这里通过直接获取他的value直接构成一个Collection的集合来直接遍历他的vlaue
Collection stringCollection=hashMap.values();
Iterator stringIterator =stringCollection.iterator();
while (stringIterator.hasNext()) {
System.out.println(stringIterator.next());
}
//这里通过entrySet方法获取一个Set类型Map.Entry泛型的集合,这个Map.Entry类型,有一个getkey和getvalue方法,这个方法是最有效的,避免了在链表里面进行的查询
Set<Map.Entry<Integer,String >> entrySet =hashMap.entrySet();
for (Map.Entry<Integer, String> entry : entrySet) {
System.out.println(“key是” + entry.getKey());
System.out.println(“value是” + entry.getValue());
}
//----------------------------------------------------------------------------------------------------
}
}
class Man implements Comparable {
int age;
@Override
public String toString() {
return "Man{" +
"age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Man)) return false;
Man man = (Man) o;
return age == man.age;
}
@Override
public int hashCode() {
return Objects.hash(age);
}
public Man() {
}
public Man(int age) {
this.age = age;
}
@Override
public int compareTo(Man o) {
return this.age - o.age;
}
}
最后
以上就是慈祥猎豹为你收集整理的Map集合的特性和遍历方法的全部内容,希望文章能够帮你解决Map集合的特性和遍历方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复