Map集合的特性和遍历方法

/**

  • 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;


}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值