当前位置: 首页 > news >正文

Java之Map接口

文章目录

  • 简述
      • Map中key-value特点
  • Map接口的常用方法
  • Map的主要实现类:HashMap
      • HashMap概述
  • Map实现类之二:LinkedHashMap
  • Map实现类之三:TreeMap
  • Map实现类之四:Hashtable(古老实现类)
  • Map实现类之五:Properties(古老的类)

简述

  • Map与Collection并列存在。用于保存具有映射关系的数据:key-value

    • Collection集合称为单列集合,元素是孤立存在的(理解为单身)。
    • Map集合称为双列集合,元素是成对存在的(理解为夫妻)。
  • Map 中的 key 和 value 都可以是任何引用类型的数据。但常用String类作为Map的“键”。

  • Map接口的常用实现类:HashMapLinkedHashMapTreeMap和``Properties。其中,HashMap是 Map 接口使用频率最高`的实现类。
    在这里插入图片描述

Map中key-value特点

这里主要以HashMap为例说明。HashMap中存储的key、value的特点如下:
在这里插入图片描述
Map 中的 key用Set来存放不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法
在这里插入图片描述

  • key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到唯一的、确定的 value,不同key对应的value可以重复。value所在的类要重写equals()方法。

  • key和value构成一个entry。所有的entry彼此之间是无序的不可重复的

Map接口的常用方法

  • 添加、修改操作:
    • Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
    • void putAll(Map m):将m中的所有key-value对存放到当前map中
  • 删除操作:
    • Object remove(Object key):移除指定key的key-value对,并返回value
    • void clear():清空当前map中的所有数据
  • 元素查询的操作:
    • Object get(Object key):获取指定key对应的value
    • boolean containsKey(Object key):是否包含指定的key
    • boolean containsValue(Object value):是否包含指定的value
    • int size():返回map中key-value对的个数
      - boolean isEmpty():判断当前map是否为空
    • boolean equals(Object obj):判断当前map和参数对象obj是否相等
  • 元视图操作的方法:
    - Set keySet():返回所有key构成的Set集合
    • Collection values():返回所有value构成的Collection集合
    • Set entrySet():返回所有key-value对构成的Set集合
      举例:
import java.util.HashMap;public class TestMapMethod {public static void main(String[] args) {//创建 map对象HashMap map = new HashMap();//添加元素到集合map.put("黄晓明", "杨颖");map.put("李晨", "李小璐");map.put("李晨", "范冰冰");map.put("邓超", "孙俪");System.out.println(map);//删除指定的key-valueSystem.out.println(map.remove("黄晓明"));System.out.println(map);//查询指定key对应的valueSystem.out.println(map.get("邓超"));System.out.println(map.get("黄晓明"));}
}

举例:

public static void main(String[] args) {HashMap map = new HashMap();map.put("许仙", "白娘子");map.put("董永", "七仙女");map.put("牛郎", "织女");map.put("许仙", "小青");System.out.println("所有的key:");Set keySet = map.keySet();for (Object key : keySet) {System.out.println(key);}System.out.println("所有的value:");Collection values = map.values();for (Object value : values) {System.out.println(value);}System.out.println("所有的映射关系:");Set entrySet = map.entrySet();for (Object mapping : entrySet) {//System.out.println(entry);Map.Entry entry = (Map.Entry) mapping;System.out.println(entry.getKey() + "->" + entry.getValue());}
}

Map的主要实现类:HashMap

HashMap概述

  • HashMap是 Map 接口使用频率最高的实现类。
  • HashMap是线程不安全的。允许添加 null 键和 null 值。
  • 存储数据采用的哈希表结构,底层使用一维数组+单向链表+红黑树进行key-value数据的存储。与HashSet一样,元素的存取顺序不能保证一致。
  • HashMap 判断两个key相等的标准是:两个 key 的hashCode值相等,通过 equals() 方法返回 true。
  • HashMap 判断两个value相等的标准是:两个 value 通过 equals() 方法返回 true。

  • **练习1:**添加你喜欢的歌手以及你喜欢他唱过的歌曲
    例如:
    在这里插入图片描述
public class SingerTest1 {public static void main(String[] args) {//创建一个HashMap用于保存歌手和其歌曲集HashMap singers = new HashMap();//声明一组key,valueString singer1 = "周杰伦";ArrayList songs1 = new ArrayList();songs1.add("双节棍");songs1.add("本草纲目");songs1.add("夜曲");songs1.add("稻香");//添加到map中singers.put(singer1,songs1);//声明一组key,valueString singer2 = "陈奕迅";List songs2 = Arrays.asList("浮夸", "十年", "红玫瑰", "好久不见", "孤勇者");//添加到map中singers.put(singer2,songs2);//遍历mapSet entrySet = singers.entrySet();for(Object obj : entrySet){Map.Entry entry = (Map.Entry)obj;String singer = (String) entry.getKey();List songs = (List) entry.getValue();System.out.println("歌手:" + singer);System.out.println("歌曲有:" + songs);}}
}
//方式2:改为HashSet实现
public class SingerTest2 {@Testpublic void test1() {Singer singer1 = new Singer("周杰伦");Singer singer2 = new Singer("陈奕迅");Song song1 = new Song("双节棍");Song song2 = new Song("本草纲目");Song song3 = new Song("夜曲");Song song4 = new Song("浮夸");Song song5 = new Song("十年");Song song6 = new Song("孤勇者");HashSet h1 = new HashSet();// 放歌手一的歌曲h1.add(song1);h1.add(song2);h1.add(song3);HashSet h2 = new HashSet();// 放歌手二的歌曲h2.add(song4);h2.add(song5);h2.add(song6);HashMap hashMap = new HashMap();// 放歌手和他对应的歌曲hashMap.put(singer1, h1);hashMap.put(singer2, h2);for (Object obj : hashMap.keySet()) {System.out.println(obj + "=" + hashMap.get(obj));}}
}//歌曲
public class Song implements Comparable{private String songName;//歌名public Song() {super();}public Song(String songName) {super();this.songName = songName;}public String getSongName() {return songName;}public void setSongName(String songName) {this.songName = songName;}@Overridepublic String toString() {return "《" + songName + "》";}@Overridepublic int compareTo(Object o) {if(o == this){return 0;}if(o instanceof Song){Song song = (Song)o;return songName.compareTo(song.getSongName());}return 0;}}
//歌手
public class Singer implements Comparable{private String name;private Song song;public Singer() {super();}public Singer(String name) {super();this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Song getSong() {return song;}public void setSong(Song song) {this.song = song;}@Overridepublic String toString() {return name;}@Overridepublic int compareTo(Object o) {if(o == this){return 0;}if(o instanceof Singer){Singer singer = (Singer)o;return name.compareTo(singer.getName());}return 0;}
}

练习2:WordCount统计

需求:统计字符串中每个字符出现的次数
String str = “aaaabbbcccccccccc”;
提示:
char[] arr = str.toCharArray(); //将字符串转换成字符数组
HashMap hm = new HashMap(); //创建双列集合存储键和值,键放字符,值放次数

public class WordCountTest {public static void main(String[] args) {String str = "aaaabbbcccccccccc";char[] arr = str.toCharArray(); // 将字符串转换成字符数组HashMap map = new HashMap(); // 创建双列集合存储键和值for (char c : arr) { // 遍历字符数组if (!map.containsKey(c)) { // 如果不包含这个键map.put(c, 1); // 就将键和值为1添加} else { // 如果包含这个键map.put(c, (int)map.get(c) + 1); // 就将键和值再加1添加进来}}for (Object key : map.keySet()) { // 遍历双列集合System.out.println(key + "=" + map.get(key));}}
}

Map实现类之二:LinkedHashMap

  • LinkedHashMap 是 HashMap 的子类
  • 存储数据采用的哈希表结构+链表结构,在HashMap存储结构的基础上,使用了一对双向链表记录添加元素的先后顺序,可以保证遍历元素时,与添加的顺序一致。
  • 通过哈希表结构可以保证键的唯一、不重复,需要键所在类重写hashCode()方法、equals()方法。
public class TestLinkedHashMap {public static void main(String[] args) {LinkedHashMap map = new LinkedHashMap();map.put("王五", 13000.0);map.put("张三", 10000.0);//key相同,新的value会覆盖原来的value//因为String重写了hashCode和equals方法map.put("张三", 12000.0);map.put("李四", 14000.0);//HashMap支持key和value为null值String name = null;Double salary = null;map.put(name, salary);Set entrySet = map.entrySet();for (Object obj : entrySet) {Map.Entry entry = (Map.Entry)obj;System.out.println(entry);}}
}

Map实现类之三:TreeMap

  • TreeMap存储 key-value 对时,需要根据 key-value 对进行排序。TreeMap 可以保证所有的 key-value 对处于有序状态
  • TreeSet底层使用红黑树结构存储数据
  • TreeMap 的 Key 的排序:
    • 自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException
    • 定制排序:创建 TreeMap 时,构造器传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口
  • TreeMap判断两个key相等的标准:两个key通过compareTo()方法或者compare()方法返回0。

public class TestTreeMap {/** 自然排序举例* */@Testpublic void test1(){TreeMap map = new TreeMap();map.put("CC",45);map.put("MM",78);map.put("DD",56);map.put("GG",89);map.put("JJ",99);Set entrySet = map.entrySet();for(Object entry : entrySet){System.out.println(entry);}}/** 定制排序** */@Testpublic void test2(){//按照User的姓名的从小到大的顺序排列TreeMap map = new TreeMap(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {if(o1 instanceof User && o2 instanceof User){User u1 = (User)o1;User u2 = (User)o2;return u1.name.compareTo(u2.name);}throw new RuntimeException("输入的类型不匹配");}});map.put(new User("Tom",12),67);map.put(new User("Rose",23),"87");map.put(new User("Jerry",2),88);map.put(new User("Eric",18),45);map.put(new User("Tommy",44),77);map.put(new User("Jim",23),88);map.put(new User("Maria",18),34);Set entrySet = map.entrySet();for(Object entry : entrySet){System.out.println(entry);}}
}class User implements Comparable{String name;int age;public User(String name, int age) {this.name = name;this.age = age;}public User() {}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}/*举例:按照age从小到大的顺序排列,如果age相同,则按照name从大到小的顺序排列* */@Overridepublic int compareTo(Object o) {if(this == o){return 0;}if(o instanceof User){User user = (User)o;int value = this.age - user.age;if(value != 0){return value;}return -this.name.compareTo(user.name);}throw new RuntimeException("输入的类型不匹配");}
}

Map实现类之四:Hashtable(古老实现类)

  • Hashtable是Map接口的古老实现类,JDK1.0就提供了。不同于HashMap,Hashtable是线程安全的。
  • Hashtable实现原理和HashMap相同,功能相同。底层都使用哈希表结构(数组+单向链表),查询速度快。
  • 与HashMap一样,Hashtable 也不能保证其中 Key-Value 对的顺序
  • Hashtable判断两个key相等、两个value相等的标准,与HashMap一致。
  • 与HashMap不同,Hashtable 不允许使用 null 作为 key 或 value。

面试题:Hashtable和HashMap的区别

HashMap:底层是一个哈希表(jdk7:数组+链表;jdk8:数组+链表+红黑树),是一个线程不安全的集合,执行效率高
Hashtable:底层也是一个哈希表(数组+链表),是一个线程安全的集合,执行效率低HashMap集合:可以存储null的键、null的值
Hashtable集合,不能存储null的键、null的值HashtableVector集合一样,在jdk1.2版本之后被更先进的集合(HashMap,ArrayList)取代了。所以HashMapMap的主要实现类,HashtableMap的古老实现类。Hashtable的子类Properties(配置文件)依然活跃在历史舞台
Properties集合是一个唯一和IO流相结合的集合

Map实现类之五:Properties(古老的类)

  • Properties 类是 Hashtable 的子类,该对象用于处理属性文件

  • 由于属性文件里的 key、value 都是字符串类型,所以 Properties 中要求 key 和 value 都是字符串类型

  • 存取数据时,建议使用setProperty(String key,String value)方法和getProperty(String key)方法

@Test
public void test01() {Properties properties = System.getProperties();String fileEncoding = properties.getProperty("file.encoding");//当前源文件字符编码System.out.println("fileEncoding = " + fileEncoding);
}
@Test
public void test02() {Properties properties = new Properties();properties.setProperty("user","songhk");properties.setProperty("password","123456");System.out.println(properties);
}@Test
public void test03() throws IOException {Properties pros = new Properties();pros.load(new FileInputStream("jdbc.properties"));String user = pros.getProperty("user");System.out.println(user);
}
http://www.lryc.cn/news/106194.html

相关文章:

  • windows系统中的命令行可以用python,pip等命令(已在系统中添加过python环境变量),但是pycharm的terminal中无法使用。
  • 编译 OneFlow 模型
  • 【kubernetes】k8s单master集群环境搭建及kuboard部署
  • 0802|IO进程线程 day5 进程概念
  • 4 Promethues监控主机和容器
  • 亚马逊买家账号ip关联怎么处理
  • NO4 实验四:生成Web工程
  • 【linux】进程
  • 电商高并发设计之SpringBoot整合Redis实现布隆过滤器
  • SpringBoot第25讲:SpringBoot集成MySQL - MyBatis 注解方式
  • 服务器返回 413 Request Entity Too Large
  • 如何一目了然地监控远程 Linux 系统
  • 9.环境对象和回调函数
  • 51单片机(普中HC6800-EM3 V3.0)实验例程软件分析概览
  • ubuntu18.04 安装php7.4-xdebug
  • java 定时任务不按照规定时间执行
  • Android复习(Android基础-四大组件)—— Activity
  • Linux系统安装部署MongoDB完整教程(图文详解)
  • CSS图片放到<div>里面,自适应宽高全部显示,点击图片跳到新页面预览,点击旋转按钮图片可旋转
  • 二阶段web基础与http协议
  • SpringBoot+Freemark根据html模板动态导出PDF
  • XPath数据提取与贴吧爬虫应用示例
  • 字符串匹配-KMP算法
  • Java面向对象之UML类图
  • 【机器学习】西瓜书学习心得及课后习题参考答案—第4章决策树
  • 2023.8.2
  • windows运行窗口常用快捷键命令
  • HDFS的QJM方案
  • 安装win版本的neo4j(2023最新版本)
  • ChatGPT结合知识图谱构建医疗问答应用 (二) - 构建问答流程