Java集合框架(四)Map
Java集合框架(四)Map
目录
具体分布
- Map(接口)
- HashMap(类)
- SortedMap(接口)
- TreeMap(类)
Map父接口
Map的特点
- 存储一对数据(键值对)(Key-Value)
- 存储无序、无下标,键不可重复,值可重复
- 在存储时,如果存储元素的key重复,则覆盖原值(新的value覆盖旧的value)
- 在删除时,通过键值删除(因为键值唯一)
Map接口的方法
-
V put(K key,V value) //将对象存入到集合中,关联键值。key重复则分布
-
Object get(Object key) // 根据键获取对应的值
-
keySet<K> //返回所有key
-
Collection<V> values() //返回包含所有值的Collection集合
-
entrySet<Map.Entry<K,V>> //键值匹配的Set集合,Set集合中的每个元素都是键值对类型
-
containsKey(A) //判断是否有键A
-
containsValue(A) //判断是否有值A
举例
public class Demo01 {
public static void main(String[] args) {
//创建map对象(<键,值>)
Map<String,String> map = new HashMap<>();
map.put("cn","中国");//(key,value)
map.put("uk","英国");
map.put("us","美国");
map.put("ap","苹果");
System.out.println("--------元素个数---------");
System.out.println(map.size());
System.out.println("--------元素的内容(键值)---------");
System.out.println(map.toString());
System.out.println("--------删除---------");
map.remove("us");
System.out.println("--------元素个数---------");
System.out.println(map.size());
System.out.println("--------元素的内容(键值)---------");
System.out.println(map.toString());
//遍历1
System.out.println("--------遍历1:通过keySet遍历---------");
//先将键转换成set类型,再用set方式遍历
//同时通过get方法直接获得键所对应的值
Set<String> k1 = map.keySet();
for (String s : k1) {
System.out.println(s+":"+map.get(s));
}
//遍历2(效率高)
System.out.println("--------遍历2:通过entrySet遍历---------");
Set<Map.Entry<String,String>> k2 = map.entrySet();//set中的每个元素都是键值对类型
for (Map.Entry<String, String> Entry : k2) {
System.out.println(Entry.getKey()+":"+Entry.getValue());
}
//判断
System.out.println("------判断是否有cn键-------");
System.out.println(map.containsKey("cn"));
System.out.println("------判断是否有泰国值-------");
System.out.println(map.containsValue("泰国"));
}
}
//输出:
--------元素个数---------
4
--------元素的内容(键值)---------
{uk=英国, cn=中国, us=美国, ap=苹果}
--------删除---------
--------元素个数---------
3
--------元素的内容(键值)---------
{uk=英国, cn=中国, ap=苹果}
--------遍历1:通过keySet遍历---------
uk:英国
cn:中国
ap:苹果
--------遍历2:通过entrySet遍历---------
uk:英国
cn:中国
ap:苹果
------判断是否有cn键-------
true
------判断是否有泰国值-------
false
HashMap (Map的实现类)
HashMap特点
-
线程不安全,运行效率快;允许用null作为key或者value
-
存储方式:哈希表(数组+链表+红黑树)
-
相同的键添加只会造成覆盖,判断是否相同是更加是不是同一个对象,而不是键的内容
通过重写key的hashcode和equals来让内容相同的键不能重复(举例)
重写hashcode和equals,通过Alt+Insert来快捷选择
-
当每个链表长度大于8,并且元素个数大于等于64时,会调整为红黑树,目的提高效率(jdk1.8)
-
当链表长度小于6时,调整成链表(jdk1.8)
举例
类(重写equals和hashCode):
public class Student {
private String name;
private int age;
public Student(){
}
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;
}
public String toString(){
return "["+this.name+" "+this.age+"]";
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
主函数:
public class Demo02 {
public static void main(String[] args) {
//键记录学生信息,值记录学生地址
HashMap<Student,String> student = new HashMap<>();
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",20);
Student s3 = new Student("王五",21);
Student s4 = new Student("赵六",19);
Student s5 = new Student("赵六",19);
student.put(s1,"北京");
student.put(s2,"天津");
student.put(s3,"上海");
student.put(s4,"武汉");
student.put(s5,"秦岭");
System.out.println("--------元素个数---------");
System.out.println(student.size());
System.out.println("--------元素的内容(键值)---------");
System.out.println(student.toString());
System.out.println("---------删除-----------");
student.remove(new Student("张三",18));
System.out.println("--------元素个数---------");
System.out.println(student.size());
System.out.println("--------元素的内容(键值)---------");
//遍历1
System.out.println("--------遍历1:通过keySet遍历---------");
Set k1 = student.keySet();
for (Object o : k1) {
System.out.println(o+":"+student.get(o));
}
//遍历2(效率高)
System.out.println("--------遍历2:通过entrySet遍历---------");
Set<Map.Entry<Student,String>> k2 = student.entrySet();
for (Map.Entry<Student, String> st : k2) {
System.out.println(st.getKey()+":"+st.getValue());
}
//判断
System.out.println("------判断是否有王五键-------");
System.out.println(student.containsKey(new Student("王五",21)));
System.out.println("------判断是否有福建值-------");
System.out.println(student.containsValue("福建"));
}
}
//输出:
--------元素个数---------
4
--------元素的内容(键值)---------
{[赵六 19]=秦岭, [张三 18]=北京, [李四 20]=天津, [王五 21]=上海}
---------删除-----------
--------元素个数---------
3
--------元素的内容(键值)---------
--------遍历1:通过keySet遍历---------
[赵六 19]:秦岭
[李四 20]:天津
[王五 21]:上海
--------遍历2:通过entrySet遍历---------
[赵六 19]:秦岭
[李四 20]:天津
[王五 21]:上海
------判断是否有王五键-------
true
------判断是否有福建值-------
false
HashSet和HashMap的区别
- HashSet里面用的就是HashMap
- 例如HashSet里面的添加add方法就是用HashMap的put实现的(用HashMap的key来保存数据,value不存东西)
扩展Hashtable
- Hashhtable接口(jdk1.0):线程安全,运行效率慢,不允许null作为key或value
- Properties实现类:
- 要求key和value都是String。通常用于配置文件的读取
- Properties可保存在流中或从流中加载
- Properties实现类:
TreeMap(Map的子接口SortedMap的实现类)
TreeMap特点
-
存储方式:红黑树(左小右大),用的时候和TreeSet一样
-
和TreeSet一样(属性过多时要用Comparable或Comparator来确定通过什么属性比较大小):
-
实现Comparable接口(举例2)
-
通过Comparator实现定制比较(比较器)(举例3)
-
举例
类:
public class Student2 implements Comparable<Student2>{
private String name;
private int age;
public Student2(){
}
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;
}
public String toString(){
return "["+this.name+" "+this.age+"]";
}
public Student2(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student2 o) {
//先看名字是否相同,再看年龄是否相同
int s1=this.age-o.age;
int s2=this.getName().compareTo(o.getName());
return s2==0?s1:s2;
}
}
主函数:
public class Demo03 {
public static void main(String[] args) {
TreeMap<Student2,String> treeMap = new TreeMap<>();
Student2 s1 = new Student2("张三",18);
Student2 s2 = new Student2("李四",20);
Student2 s3 = new Student2("王五",21);
Student2 s4 = new Student2("赵六",19);
treeMap.put(s1,"北京");
treeMap.put(s2,"天津");
treeMap.put(s3,"上海");
treeMap.put(s4,"武汉");
System.out.println("--------元素个数---------");
System.out.println(treeMap.size());
System.out.println("--------元素的内容(键值)---------");
System.out.println(treeMap.toString());
System.out.println("------------------键相同会被覆盖--------------------");
treeMap.put(new Student2("赵六",19),"新疆");
System.out.println("--------元素个数---------");
System.out.println(treeMap.size());
System.out.println("--------元素的内容(键值)---------");
System.out.println(treeMap.toString());
System.out.println("--------元素的内容(键值)---------");
//遍历1
System.out.println("--------遍历1:通过keySet遍历---------");
Set k1 = treeMap.keySet();
for (Object o : k1) {
System.out.println(o+":"+treeMap.get(o));
}
//遍历2(效率高)
System.out.println("--------遍历2:通过entrySet遍历---------");
Set<Map.Entry<Student2,String>> k2 = treeMap.entrySet();
for (Map.Entry<Student2, String> st : k2) {
System.out.println(st.getKey()+":"+st.getValue());
}
//判断
System.out.println("------判断是否有王五键-------");
System.out.println(treeMap.containsKey(new Student2("王五",21)));
System.out.println("------判断是否有福建值-------");
System.out.println(treeMap.containsValue("武汉"));
}
}
//输出:
--------元素个数---------
4
--------元素的内容(键值)---------
{[张三 18]=北京, [李四 20]=天津, [王五 21]=上海, [赵六 19]=武汉}
------------------键相同会被覆盖--------------------
--------元素个数---------
4
--------元素的内容(键值)---------
{[张三 18]=北京, [李四 20]=天津, [王五 21]=上海, [赵六 19]=新疆}
--------元素的内容(键值)---------
--------遍历1:通过keySet遍历---------
[张三 18]:北京
[李四 20]:天津
[王五 21]:上海
[赵六 19]:新疆
--------遍历2:通过entrySet遍历---------
[张三 18]:北京
[李四 20]:天津
[王五 21]:上海
[赵六 19]:新疆
------判断是否有王五键-------
true
------判断是否有福建值-------
false
TreeSet和TreeMap的区别
- TreeSet里面用的就是TreeMap
- 例如TreeSet里面的添加add方法就是用TreeMap的put实现的(用TreeMap的key来保存数据,value不存东西)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现