【Java学习笔记】Map接口及其实现类

目录

1.Map集合的特点

2.Map集合的功能概述

2.1 添加功能

2.2 删除功能

2.3 判断功能

2.4长度功能

2.5获取功能

3.Map集合的遍历

3.1 根据键找值

3.2 根据键值对对象找键和值

4.HashMap的概述

4.1 HashMap案例1:键String值String

4.2 HashMap案例2:键Integer值String

4.3 HashMap案例3:键String值Student

4.4 HashMap案例4:键Student值String

5.LinkedHashMap的概述和使用

6.TreeMap概述

6.1 TreeMap案例1:键是String值是String

6.2 TreeMap案例2:键是Student值是String

7.面试题

7.1 Hashtable和HashMap的区别?

7.2 List、Set、Map等接口是否都继承自Map接口?

7.3 Collection和Collections的区别?


1.Map集合的特点

  • 将键映射到值的对象
  • 一个映射不能包含重复的键
  • 每个键最多只能映射到一个值

2.Map集合的功能概述

2.1 添加功能

  • V put(K key,V value):添加元素

2.2 删除功能

  • V remove(Object key):根据键删除键值对元素,并返回值
  • void clear():移除所有的键值对元素

2.3 判断功能

  • boolean containsKey(Object key):判断集合是否包含指定的键
  • boolean containsValue(Object value):判断集合是否包含指定的值
  • boolean isEmpty():判断集合是否为空

2.4长度功能

  • int size():返回集合中键值对的对数

2.5获取功能

  • Set<K> keySet():获取集合中所有键的集合
  • V get(Object key):根据键获取值
  • Collection<V> values():获取集合中所有值的集合
  • Set<Map.Entry<K,V>> entrySet():返回的是键值对对象的集合

3.Map集合的遍历

3.1 根据键找值

分析步骤如下:

  • 获取所有的键
  • 遍历键的集合,获取得到每一个键
  • 根据键去找值

部分代码如下:

// 创建集合对象
Map<String, String> map = new HashMap<String, String>();

// 向集合中添加元素
map.put("杨过", "小龙女");
map.put("杨康", "穆念慈");
map.put("郭靖", "黄蓉");
map.put("杨玄风", "梅超风");
		
// 获取集合中所有键的集合
Set<String> set = map.keySet();
// 遍历set,得到每一个key
for (String key : set) {
	// 根据键去找值
	String value = map.get(key);
	System.out.println(key + "---" + value);
}

3.2 根据键值对对象找键和值

分析步骤如下:

  • 获取所有键值对对象的集合
  • 循环遍历键值对对象的集合,得到每一个键值对对象
  • 根据键值对对象得到键和值

部分代码如下:

// 创建集合对象
Map<String, String> map = new HashMap<String, String>();

// 向集合中添加元素
map.put("杨过", "小龙女");
map.put("杨康", "穆念慈");
map.put("郭靖", "黄蓉");
map.put("杨玄风", "梅超风");
		
// 获取键值对对象的集合
Set<Map.Entry<String, String>> entrySet = map.entrySet();
// 循环遍历键值对对象的集合,得到每一个键值对对象
for (Map.Entry<String, String> entry : entrySet) {
	// 根据键值对对象得到键和值
	String key = entry.getKey();
	String value = entry.getValue();
	System.out.println(key + "---" + value);
}

4.HashMap的概述

  • HashMap是基于哈希表的Map接口的实现。
  • 哈希表的作用是用来保证的键的唯一性的。
  • 哈希表结构底层依赖hashcode()方法和equals()方法!

4.1 HashMap案例1:键String值String

// 创建集合对象
HashMap<String, String> hm = new HashMap<String, String>();

// 向集合中添加元素
hm.put("allan", "男");
hm.put("bella", "女");
hm.put("zhangsan", "女");

// 遍历
// 获取所有键的集合
Set<String> set = hm.keySet();
for (String key : set) {
	// 根据键去找值
	String value = hm.get(key);
	System.out.println(key + "---" + value);
}

4.2 HashMap案例2:键Integer值String

// 创建集合对象
HashMap<Integer, String> hm = new HashMap<Integer, String>();

// 向集合中添加元素
hm.put(28, "allan");
hm.put(2, "bella");
hm.put(28, "zhangsan");
hm.put(27, "allan");

// 遍历
// 获取所有键的集合
Set<Integer> set = hm.keySet();
for (Integer key : set) {
	// 根据键找值
	String value = hm.get(key);
	System.out.println(key + "---" + value);
}

4.3 HashMap案例3:键String值Student

Student.java的代码:

public class Student {
	private String name;
	private int age;
	
	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		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;
	}

}
// 创建集合对象
HashMap<String, Student> hm = new HashMap<String, Student>();

// 创建学生对象
Student s1 = new Student("allan", 27);
Student s2 = new Student("bella", 2);
Student s3 = new Student("zhangsan", 28);
Student s4 = new Student("allan", 27);

// 向集合中添加元素
hm.put("spring001", s1);
hm.put("spring006", s2);
hm.put("spring002", s3);
hm.put("spring008", s4);

// 遍历
// 获取所有键的集合
Set<String> set = hm.keySet();
for (String key : set) {
	Student s = hm.get(key);
	System.out.println(key + "---" + s.getName() + "---" + s.getAge());
}

4.4 HashMap案例4:键Student值String

要求:如果两个对象的成员变量值都相同,则为同一个对象。

分析:HashMap是基于哈希表的Map接口的实现,而哈希表的底层依赖hashcode()方法和equals()方法。在Student类中并没有重写这两个方法,所以默认使用的Object类的hashcode()和equals()方法,这时候学生对象的hash值是不一样的,所以所有的学生对象都会输出!

解决方法:在Student类中重写hashcode()方法和equals()方法!

Student.java代码如下:

package com.hw.map02;

public class Student {
	private String name;
	private int age;
	
	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		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;
		Student other = (Student) 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;
	}
}

测试类代码如下:

// 创建集合对象
HashMap<Student, String> map = new HashMap<Student, String>();
		
// 创建学生对象
Student s1 = new Student("貂蝉", 27);
Student s2 = new Student("王昭君", 30);
Student s3 = new Student("西施", 33);
Student s4 = new Student("杨玉环", 35);
Student s5 = new Student("貂蝉", 27);
		
// 添加元素
map.put(s1, "三国");
map.put(s2, "汉朝");
map.put(s3, "春秋战国");
map.put(s4, "唐朝");
map.put(s5, "隋朝");
		
// 获取集合中所有键的集合
Set<Student> set = map.keySet();
for (Student stu : set) {
	String value = map.get(stu);
	System.out.println(stu.getName() + "---" + stu.getAge() + "---" + value);
}

运行结果如下:

貂蝉---27---隋朝
西施---33---春秋战国
杨玉环---35---唐朝
王昭君---30---汉朝

5.LinkedHashMap的概述和使用

LinkedHashMap是Map接口的哈希表和链接的实现,具有可预知的迭代顺序。

  • 由哈希表保证键的唯一性
  • 由链表保证键的有序(存储和取出的顺序一致)

LinkedHashMap保证了记录的插入顺序,在遍历LinkedHashMap时,先得到的记录是先插入的!

部分代码如下:

// 创建集合对象
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();

// 向集合中添加元素
map.put("spring_001", "hello");
map.put("spring_003", "world");
map.put("spring_001", "javaee");
map.put("spring_002", "hello");
map.put("spring_003", "html");
map.put("spring_004", "javascript");

// 获取集合中键的集合
Set<String> set = map.keySet();
for (String key : set) {
	String value = map.get(key);
	System.out.println(key + "---" + value);
}

运行结果如下:

spring_001---javaee
spring_003---html
spring_002---hello
spring_004---javascript

6.TreeMap概述

TreeMap是基于二叉树的Map接口的实现。

键是二叉树结构,可以保证键的排序和唯一性!

下面来看两个TreeMap的案例!

6.1 TreeMap案例1:键是String值是String

// 创建集合对象
// 当构造方法为空时,使用自然排序进行排序
TreeMap<String, String> tm = new TreeMap<String, String>();

// 向集合中添加元素
tm.put("liangchaowei", "刘嘉玲");
tm.put("dengchao", "孙俪");
tm.put("huangxiaoming", "杨颖");
tm.put("zhangjie", "谢娜");
tm.put("huangxiaoming", "范冰冰");

// 遍历
Set<String> set = tm.keySet();
for (String key : set) {
	String value = tm.get(key);
	System.out.println(key + "---" + value);
}

运行结果如下:

dengchao---孙俪
huangxiaoming---范冰冰
liangchaowei---刘嘉玲
zhangjie---谢娜

6.2 TreeMap案例2:键是Student值是String

Student.java代码如下:

package cn.itcast_04;

public class Student {
	private String name;
	private int age;
	
	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		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;
	}
	
	
}

TreeMapDemo2.java代码如下:

package com.hw.map02;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;

/**
 * TreeMap:键是二叉树结构,可以保证键的排序和唯一性
 * 
 * TreeMap<Student, String> 
 * 		键:Student 
 * 		值:String
 * 
 * 使用比较器排序,按照年龄从小到大排序
 * 
 * @author HW
 * 
 */
public class TreeMapDemo2 {
	public static void main(String[] args) {
		// 创建集合对象
		// 当一个方法的参数是接口时,真正需要的是该接口实现类的对象
		TreeMap<Student, String> tm = new TreeMap<Student, String>(new Comparator<Student>() {

					public int compare(Student s1, Student s2) {
						int num1 = s1.getAge() - s2.getAge();
						int num2 = (num1 == 0) ? (s1.getName().compareTo(s2
								.getName())) : num1;
						return num2;
					}
			
		});

		// 创建学生对象
		Student s1 = new Student("allan", 27);
		Student s2 = new Student("bella", 3);
		Student s3 = new Student("ella", 28);
		Student s4 = new Student("bella", 2);
		Student s5 = new Student("allan", 27);

		// 向集合中添加元素
		tm.put(s1, "男");
		tm.put(s2, "女");
		tm.put(s3, "女");
		tm.put(s4, "男");
		tm.put(s5, "女");
		
		// 获取集合中键的集合
		Set<Student> set = tm.keySet();
		for (Student stu : set) {
			String value = tm.get(stu);
			System.out.println(stu.getName() + "---" + stu.getAge() + "---" + value);
		}
	}
}

运行结果如下:

bella---2---男
bella---3---女
allan---27---女
ella---28---女

7.面试题

7.1 Hashtable和HashMap的区别?

  • Hashtable:线程安全,效率低。不允许null键和null值
  • HashMap:线程不安全,效率高。允许null键和null值

7.2 List、Set、Map等接口是否都继承自Map接口?

  • List、Set不是继承自Map接口,它们继承自Collection接口
  • Map接口本身就是一个顶层接口

7.3 Collection和Collections的区别?

  • Collection:是单列集合的顶层接口,有子接口List和Set。
  • Collections:是针对集合操作的工具类,都是静态方法,包括对集合进行排序和二分查找的方法

猜你喜欢

转载自blog.csdn.net/weixin_44679832/article/details/105439510