Map

将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值。除此之外你得明确的是Map是一个接口你得使用实现Map的类来实例化。其次是Map中数据存储格式是K-V键值对方法存储。

Map接口和Collection接口的不同

  • Map是双列的,Collection是单列的
  • Map的键唯一,Collection的子体系Set是唯一的
  • Map集合的数据结构值针对键有效,跟值无关
  • Collection集合的数据结构是针对元素有效

Map集合常用功能

  • 添加功能

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

      • 如果键是第一次存储,就直接存储键值对元素,返回null
      • 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
  • 删除功能
    • V remove(Object key):根据键删除键值对元素,并把值返回
  • 判断功能
    • boolean containsKey(Object key):判断集合是否包含指定的键
    • boolean containsValue(Object value):判断集合是否包含指定的值
    • boolean isEmpty():判断集合是否为空
  • 获取功能
    • Set<Map.Entry<K,V>> entrySet():返回此映射中包含的映射关系的 Set 视图,也就是返回一个键值对整体。
    • V get(Object key):根据键获取值
    • Set keySet():获取集合中所有键的集合
    • Collection values():获取集合中所有值的集合
  • 长度功能
    • int size():返回集合中的键值对的对数

代码实例

 public class MapDemo {public static void main(String[] args) {// 创建集合对象Map<String, String> map = new HashMap<String, String>();// 添加元素// System.out.println("put:" + map.put("文章", "马伊俐"));// System.out.println("put:" + map.put("文章", "姚笛"));map.put("邓超", "孙俪");map.put("黄晓明", "杨颖");map.put("周杰伦", "蔡依林");map.put("刘恺威", "杨幂");// void clear():移除所有的键值对元素// map.clear();// V remove(Object key):根据键删除键值对元素,并把值返回// System.out.println("remove:" + map.remove("黄晓明"));// System.out.println("remove:" + map.remove("黄晓波"));// boolean containsKey(Object key):判断集合是否包含指定的键// System.out.println("containsKey:" + map.containsKey("黄晓明"));// System.out.println("containsKey:" + map.containsKey("黄晓波"));// boolean isEmpty():判断集合是否为空// System.out.println("isEmpty:"+map.isEmpty());          //int size():返回集合中的键值对的对数System.out.println("size:"+map.size());// 输出集合名称System.out.println("map:" + map);}}

获取功能:

 public class MapDemo2 {public static void main(String[] args) {// 创建集合对象Map<String, String> map = new HashMap<String, String>();// 创建元素并添加元素map.put("邓超", "孙俪");map.put("黄晓明", "杨颖");map.put("周杰伦", "蔡依林");map.put("刘恺威", "杨幂");// V get(Object key):根据键获取值System.out.println("get:" + map.get("周杰伦"));System.out.println("get:" + map.get("周杰")); // 返回nullSystem.out.println("----------------------");// Set<K> keySet():获取集合中所有键的集合Set<String> set = map.keySet();// 遍历Set 增强for 或者迭代器 反正就是Collection的遍历方式for (String key : set) {System.out.println(key);}System.out.println("----------------------");// Collection<V> values():获取集合中所有值的集合Collection<String> con = map.values();for (String value : con) {System.out.println(value);}}}

Map集合的遍历:

遍历思路一: A:获取所有的键–> B:遍历键的集合,获取得到每一个键 -->C:根据键去找值。

示例:

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

遍历思路二: A:获取所有键值对对象的集合–>B:遍历键值对对象的集合,得到每一个键值对对象–>C:根据键值对对象获取键和值。

示例:

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

图示对比:

HashMap

键是哈希表结构,可以保证键的唯一性.需要注意的是当键为类类型的时候,需要重写类的equals和hashcode方法.

 public int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic 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;}

LinkedHashMap

Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。

TreeMap

键是红黑树结构,可以保证键的排序和唯一性。无参构造则是自然排序,前面的文章说过了。

示例:

 // 创建集合对象TreeMap<Student, String> tm = new TreeMap<Student, String>(new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {// 主要条件int num = s1.getAge() - s2.getAge();// 次要条件int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;return num2;}});// 创建学生对象Student s1 = new Student("潘安", 30);Student s2 = new Student("柳下惠", 35);Student s3 = new Student("唐伯虎", 33);Student s4 = new Student("燕青", 32);Student s5 = new Student("唐伯虎", 33);// 存储元素tm.put(s1, "宋朝");tm.put(s2, "元朝");tm.put(s3, "明朝");tm.put(s4, "清朝");tm.put(s5, "汉朝");// 遍历Set<Student> set = tm.keySet();for (Student key : set) {String value = tm.get(key);System.out.println(key.getName() + "---" + key.getAge() + "---"+ value);}

统计字符串中每个字符出现次数:

图解思路

示例代码

 /** 需求 :"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)* * 分析:*         A:定义一个字符串(可以改进为键盘录入)*       B:定义一个TreeMap集合*            键:Character*            值:Integer*       C:把字符串转换为字符数组*      D:遍历字符数组,得到每一个字符*        E:拿刚才得到的字符作为键到集合中去找值,看返回值*           是null:说明该键不存在,就把该字符作为键,1作为值存储*            不是null:说明该键存在,就把值加1,然后重写存储该键和值*       F:定义字符串缓冲区变量*       G:遍历集合,得到键和值,进行按照要求拼接*        H:把字符串缓冲区转换为字符串输出* * 录入:linqingxia* 结果:result:a(1)g(1)i(3)l(1)n(2)q(1)x(1)*/public class TreeMapDemo {public static void main(String[] args) {// 定义一个字符串(可以改进为键盘录入)Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String line = sc.nextLine();// 定义一个TreeMap集合TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();//把字符串转换为字符数组char[] chs = line.toCharArray();//遍历字符数组,得到每一个字符for(char ch : chs){//拿刚才得到的字符作为键到集合中去找值,看返回值Integer i =  tm.get(ch);//是null:说明该键不存在,就把该字符作为键,1作为值存储if(i == null){tm.put(ch, 1);}else {//不是null:说明该键存在,就把值加1,然后重写存储该键和值i++;tm.put(ch,i);}}//定义字符串缓冲区变量StringBuilder sb=  new StringBuilder();//遍历集合,得到键和值,进行按照要求拼接Set<Character> set = tm.keySet();for(Character key : set){Integer value = tm.get(key);sb.append(key).append("(").append(value).append(")");}//把字符串缓冲区转换为字符串输出String result = sb.toString();System.out.println("result:"+result);}}

Collections 类

public class Collectionsextends Object 是一个针对集合操作的工具类,都是静态方法。

常见的几个小方法:

 A:public static <T> void sort(List<T> list) 默认情况自然排序B:public static <T> int binarySearch(List<?> list,T key) 二分查找C:public static <T> T max(Collection<?> coll) 最大值D:public static void reverse(List<?> list)翻转E:public static void shuffle(List<?> list)随机置换

案例

  • 基础方法使用
     public static void main(String[] args) {// 创建集合对象List<Integer> list = new ArrayList<Integer>();// 添加元素list.add(30);list.add(20);list.add(50);list.add(10);list.add(40);System.out.println("list:" + list);// public static <T> void sort(List<T> list):排序 默认情况下是自然顺序。// Collections.sort(list);// System.out.println("list:" + list);// [10, 20, 30, 40, 50]// public static <T> int binarySearch(List<?> list,T key):二分查找// System.out// .println("binarySearch:" + Collections.binarySearch(list, 30));// System.out.println("binarySearch:"// + Collections.binarySearch(list, 300));// public static <T> T max(Collection<?> coll):最大值// System.out.println("max:"+Collections.max(list));// public static void reverse(List<?> list):反转// Collections.reverse(list);// System.out.println("list:" + list);//public static void shuffle(List<?> list):随机置换Collections.shuffle(list);System.out.println("list:" + list);}
  • 自定义对象排序
     // 创建集合对象List<Student> list = new ArrayList<Student>();// 创建学生对象Student s1 = new Student("林青霞", 27);Student s2 = new Student("风清扬", 30);Student s3 = new Student("刘晓曲", 28);Student s4 = new Student("武鑫", 29);Student s5 = new Student("林青霞", 27);// 添加元素对象list.add(s1);list.add(s2);list.add(s3);list.add(s4);list.add(s5);// 排序// 自然排序// Collections.sort(list);// 比较器排序// 如果同时有自然排序和比较器排序,以比较器排序为主Collections.sort(list, new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {int num = s2.getAge() - s1.getAge();int num2 = num == 0 ? s1.getName().compareTo(s2.getName()): num;return num2;}});// 遍历集合for (Student s : list) {System.out.println(s.getName() + "---" + s.getAge());}
  • 模拟斗地主洗牌发牌
import java.util.ArrayList;import java.util.Collections;/** 模拟斗地主洗牌和发牌* * 分析:*        A:创建一个牌盒*       B:装牌*       C:洗牌*       D:发牌*       E:看牌*/public class PokerDemo {public static void main(String[] args) {// 创建一个牌盒ArrayList<String> array = new ArrayList<String>();// 装牌// 黑桃A,黑桃2,黑桃3,...黑桃K// 红桃A,...// 梅花A,...// 方块A,...// 定义一个花色数组String[] colors = { "♠", "♥", "♣", "♦" };// 定义一个点数数组String[] numbers = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10","J", "Q", "K" };// 装牌for (String color : colors) {for (String number : numbers) {array.add(color.concat(number));}}array.add("小王");array.add("大王");// 洗牌Collections.shuffle(array);// System.out.println("array:" + array);// 发牌ArrayList<String> xianglei = new ArrayList<String>();ArrayList<String> linQingXia = new ArrayList<String>();ArrayList<String> liuYi = new ArrayList<String>();ArrayList<String> diPai = new ArrayList<String>();for (int x = 0; x < array.size(); x++) {if (x >= array.size() - 3) {diPai.add(array.get(x));} else if (x % 3 == 0) {fengQingYang.add(array.get(x));} else if (x % 3 == 1) {linQingXia.add(array.get(x));} else if (x % 3 == 2) {liuYi.add(array.get(x));}}// 看牌lookPoker("向磊", fengQingYang);lookPoker("林青霞", linQingXia);lookPoker("刘意", liuYi);lookPoker("底牌", diPai);}public static void lookPoker(String name, ArrayList<String> array) {System.out.print(name + "的牌是:");for (String s : array) {System.out.print(s + " ");}System.out.println();}}

如何对发出来的牌进行排序?

图解:

代码

 /** 思路:*         A:创建一个HashMap集合*        B:创建一个ArrayList集合*      C:创建花色数组和点数数组*      D:从0开始往HashMap里面存储编号,并存储对应的牌*        同时往ArrayList里面存储编号即可。*      E:洗牌(洗的是编号)*      F:发牌(发的也是编号,为了保证编号是排序的,就创建TreeSet集合接收)*      G:看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)*/public class PokerDemo {public static void main(String[] args) {// 创建一个HashMap集合HashMap<Integer, String> hm = new HashMap<Integer, String>();// 创建一个ArrayList集合ArrayList<Integer> array = new ArrayList<Integer>();// 创建花色数组和点数数组// 定义一个花色数组String[] colors = { "♠", "♥", "♣", "♦" };// 定义一个点数数组String[] numbers = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q","K", "A", "2", };// 从0开始往HashMap里面存储编号,并存储对应的牌,同时往ArrayList里面存储编号即可。int index = 0;for (String number : numbers) {for (String color : colors) {String poker = color.concat(number);hm.put(index, poker);array.add(index);index++;}}hm.put(index, "小王");array.add(index);index++;hm.put(index, "大王");array.add(index);// 洗牌(洗的是编号)Collections.shuffle(array);// 发牌(发的也是编号,为了保证编号是排序的,就创建TreeSet集合接收)TreeSet<Integer> fengQingYang = new TreeSet<Integer>();TreeSet<Integer> linQingXia = new TreeSet<Integer>();TreeSet<Integer> liuYi = new TreeSet<Integer>();TreeSet<Integer> diPai = new TreeSet<Integer>();for (int x = 0; x < array.size(); x++) {if (x >= array.size() - 3) {diPai.add(array.get(x));} else if (x % 3 == 0) {fengQingYang.add(array.get(x));} else if (x % 3 == 1) {linQingXia.add(array.get(x));} else if (x % 3 == 2) {liuYi.add(array.get(x));}}// 看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)lookPoker("风清扬", fengQingYang, hm);lookPoker("林青霞", linQingXia, hm);lookPoker("刘意", liuYi, hm);lookPoker("底牌", diPai, hm);}// 写看牌的功能public static void lookPoker(String name, TreeSet<Integer> ts,HashMap<Integer, String> hm) {System.out.print(name + "的牌是:");for (Integer key : ts) {String value = hm.get(key);System.out.print(value + " ");}System.out.println();}}

总结

HashMap和Hashtable的区别?

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

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

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

Collection和Collections的区别

  • Collection 是单列集合的顶层接口,有两个子接口List和Set
  • Collections 是针对集合进行操作的工具类,可以对集合进行排序和查找等

Java基础总结篇---Map接口相关推荐

  1. 超详细的Java面试题总结(二)之Java基础知识篇

    系列文章: 超详细的Java面试题总结(一)之Java基本知识 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(三)之Java集合篇常见问题 超详细的Java面试题总 ...

  2. Java面向对象编程篇3——接口与抽象类

    Java面向对象编程篇3--接口与抽象类 1.接口(interface) 接口中可以含有变量和方法.但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是pub ...

  3. Java基础知识之Map:compute, computeIfAbsent, computeIfPresent

    Java基础知识之Map:compute, computeIfAbsent, computeIfPresent 功能 default V compute(K key, BiFunction<? ...

  4. JAVA中整型常量的长度,Java基础入门篇(三)——Java常量、变量,

    Java基础入门篇(三)--Java常量.变量, 一.Java常量 (一)什么是常量 常量指的是在程序中固定不变的值,是不能改变的数据.在Java中,常量包括整型常量.浮点型常量.布尔常量.字符常量等 ...

  5. 初学Java基础学习——抽象类和接口的区别

    初学Java基础学习--抽象类和接口的区别 一.关键字 1)抽象类的关键字 abstract class A{//定义一个抽象类: } class Test extends A{//子类使用exten ...

  6. (Java实习生)每日10道面试题打卡——Java基础知识篇

    临近秋招,备战暑期实习,祝大家每天进步亿点点! 本篇总结的是Java基础知识相关的面试题,后续会每日更新~ 1.请你说一下什么是面向对象? Java是面向对象的编程语言,不同于C语言是面向过程的.对于 ...

  7. (Java实习生)每日10道面试题打卡——Java基础知识篇2

    临近秋招,备战暑期实习,祝大家每天进步亿点点! 本篇总结的是Java基础知识相关的面试题,后续会每日更新~ 1.请你说一下Java中的IO流?以及他们的分类和作用? IO 流的分类: 按照数据流的方向 ...

  8. Java语言-27:Map接口

    1.Map接口: Map接口是一种双列集合(Collectiom是单列),它的每个元素都包含一个键对象(Key)和一个值(Value)对象,称之为键值对,他们之间的关系是映射关系.从Map集合中访问元 ...

  9. 「Java面试题精华集」Java基础知识篇(2022最新版)附PDF版

    两个星期前,我和我的好朋友决定做一系列的 Java 知识点常见重要问题的小册.小册的标准就一个,那就是:取精华,取重点.每一本小册,我们都会充分关注我们所总结的知识点是否达到这个标准. 昨天晚上终于把 ...

最新文章

  1. AHOI2008 聚会
  2. 为何BERT在 NLP 中的表现如此抢眼?
  3. 锚杆拉拔试验弹性模量计算_土钉、锚杆拉拔试验检测方案 - 图文 -
  4. 即时通讯音视频开发(六):如何开始音频编解码技术的学习
  5. java添加文字水印插件_java之io添加文字水印
  6. 【转】strcpy溢出的攻击示例
  7. IDEA中jsp页面写out.println会报错?
  8. MTK 驱动开发(30)---Memory 移植
  9. 老用户们,苹果没有忘了你们!
  10. linux网卡端口绑定bond,Linux下双网卡绑定bond0
  11. Google earth
  12. 定时任务_SpringTask 定时任务
  13. c语言水库抽样算法代码,LeetCode---蓄水池抽样算法
  14. 贝叶斯分析好坏_交易必读|浅谈贝叶斯分析
  15. 手机远程计算机桌面,远程桌面预览Windows10,您可以远程通过手机控制电脑
  16. arcgis 线自动构面的方法一例
  17. dva的使用,附带一个Demo
  18. Java前端和后端的区别?
  19. 第30节 程序中的三国天下
  20. Windows消息概述

热门文章

  1. 如何申请创建数据分析项目组合
  2. Android 正则表达式验证手机和邮箱格式是否正确
  3. Java - LogicControl -逻辑控制
  4. csdn最牛最全的使用python自动发送邮件
  5. CSharp求圆周长以及面积
  6. XWifiMouse早期写的一个Android鼠标App
  7. Chapter One:学习 Chrome 开发者工具
  8. 接近8000字的Spring/Spring常用注解总结|安排|
  9. Python生成+识别二维码
  10. 14种方法帮你养成终生的阅读习惯