详解 HashMap

本篇博文的知识点,在我们的日常生活中,应用十分广阔。比如:每个学生,都有自己的对应的学号、每一个公民,都有自己的身份证号… … 相信看到这里,有的同学基本上已经猜到了这个类的主要用途。那么,话不多说,我们开始主题的讲解吧!

(有关Map集合的基本性质,请观看本人博文—— 《详解 Map集合》

HashMap:

特点

允许插入null键 null值
线程不安全,效率高

注意事项

注意 键 的类型是否重写了equals()方法
(是否录入是靠 已存在HashMap集合中的键值对的 键要录入的键值对的 键equals()的返回值

  • 返回true,则 用新键值对覆盖旧键值对
  • 返回false,则 直接录入新键值对)

HashMap在Map集合中,基于Map接口,并没有专属常用API,所以,本人在这里就直接来展示下对这个类的使用:

首先,本人来给出一个例子:

package about_hashtable;

import java.util.HashMap;

public class Test {
	
	public static void main(String[] args) {
		HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put(new String("古巨基"),"s001");
        hashMap.put(new String("张根硕"), "s002");
        hashMap.put(new String("吴孟达"), null);
        hashMap.put(null, null);

        System.out.println(hashMap.values());
	}
	
}

现在让我们来看一下运行结果:
在这里插入图片描述
可以看到,我们用HashMap存储的键值对:
键和值都可以是null


本人再来给出一个奇怪的例子

首先本人给出一个存储“键”信息的People类:

package about_hashtable;

public class People{
    private String name;
    private int age;

    public People() {
    }

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

现在,本人再来给出一个测试类:

package about_hashtable;

import java.util.HashMap;

public class Test {
	
	public static void main(String[] args) {
		HashMap<People, String> hashMap = new HashMap<>();
        hashMap.put(new People("古巨基", 23),"s001");
        hashMap.put(new People("张根硕", 26), "s002");
        hashMap.put(new People("古巨基", 23), "s003");
        hashMap.put(new People("张根硕", 26), "s004");

        System.out.println(hashMap.values());
	}
	
}

那么,让我们来看一下运行结果:
在这里插入图片描述

这时候可能有同学会产生疑问:
在《详解 Map集合》的讲解中,说到:
若录入 “键相同” 的键值对,则会 覆盖旧的键值对
那么,为什么还是录入了四个信息呢?
答曰:每个录入的信息是通过new出来的,它们的地址值是不同的。
而我们若是想根据“键的内容”去存储,而不是根据“键的地址”去存储的话,就要重写键的类的equals()方法


现在,本人来重写下People类的equals()方法:

package about_hashtable;

public class People{
    private String name;
    private int age;

    public People() {
    }

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
    

    @Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.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;
		People other = (People) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	@Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

那么,现在我们再来看一下运行结果:
在这里插入图片描述
可以看到,在我们重写了“键”所属的类的equals()方法后,当我们再次向HashMap中存放数据时,就会按照“键的equals()的返回值”来决定存放不存放了。


那么,相对地,本人再来提出一个奇怪的例子:
现在本人来对测试类做些修改:

package about_hashtable;

import java.util.HashMap;

public class Test {
	
	public static void main(String[] args) {
		HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put(new String("古巨基"),"s001");
        hashMap.put(new String("张根硕"), "s002");
        hashMap.put(new String("古巨基"), "s003");
        hashMap.put(new String("张根硕"), "s004");

        System.out.println(hashMap.values());
	}
	
}

那么,现在我们来看一下运行结果:
在这里插入图片描述
可以看到,我们并没有重写String的equals()方法,但是却按照每个键的内容是否相同决定存储了。

相信看过前几篇博文的同学现在已经知道了答案——String类内部已经重写了equals()方法。


那么,在最后,本人再来讲解一个知识点 —— HashMap的遍历:

HashMap的遍历

  • 法1:
    通过keySet()方法获取键集,通过遍历键集来遍历值集
  • 法2:
    通过entrySet()方法获得Entry类型的Set集,通过遍历这个集,同时调用getKey() 和 getValue()方法,就能获取原HashMap的所有存储信息了

那么,现在本人来展示下这两种遍历方法的应用:
法1(通过keySet()方法):

package about_hashtable;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {

	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		
		map.put("唔系", "渣渣辉");
		map.put("贪玩蓝月", "一款里从喂顽固的游戏");
		map.put("开局", "只需三分钟");
		map.put("不发一分钱", "装备全靠捡");
		
		Set<String> keySet = map.keySet();
		System.out.println(keySet);
		
		for (String key : keySet) {
			System.out.println("----------------------");
			System.out.println(key);
			System.out.println(map.get(key));
		}
	}

}

那么,本人在来展示下运行结果:
在这里插入图片描述

法2(通过entrySet()方法):

package about_hashtable;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Test {

	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		
		map.put("唔系", "渣渣辉");
		map.put("贪玩蓝月", "一款里从喂顽固的游戏");
		map.put("开局", "只需三分钟");
		map.put("不发一分钱", "装备全靠捡");
		
		Set<Entry<String, String>> entries = map.entrySet();
		System.out.println(entries);
		
		for (Entry<String, String> entry : entries) {
			System.out.println("----------------------");
			System.out.println(entry);
			System.out.println(entry.getKey());
			System.out.println(entry.getValue());
		}
	}

}

那么,本人在来展示下运行结果:
在这里插入图片描述


那么,有关HashMap的基本知识点也就这些了。

(有关Map集合的基本性质,请观看本人博文—— 《详解 Map集合》
(本人 集合框架 的总集篇博文链接:https://www.cnblogs.com/codderYouzg/p/12416560.html

posted @ 2020-03-04 22:33  在下右转,有何贵干  阅读(176)  评论(0编辑  收藏  举报