Map 双列集合语法详解一、双列集合的特点单列集合“服部平次”“黑羽快斗”“江户川柯南”双列集合**key****value**江户川柯南毛利兰黑羽快斗中森青子服部平次荷叶双列集合一次需要存一对数据,分别为键和值键不可以重复,值可以重复键和值是一一对应的,每一个键只能找到自己对应的值键 值 这个整体我们称之为键值对或者键值对对象,在Java中叫做Entry对象‍二、Map的常见APIMap是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的方法名称说明V put(K key,V value)添加元素V remove(Object key)根据键删除键值对元素void clear()移除所有的键值对元素boolean containsKey(Object key)判断集合是否包含指定的键boolean containsValue(Object value)判断集合是否包含指定的值boolean isEmpty()判断集合是否为空int size()集合的长度,也就是集合中键值对的个数publicclassMapDemo1{publicstaticvoidmain(String[]args){MapString,StringmnewHashMap();/** * 添加元素 * put方法的细节: * 在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中,方法返回null * 在添加数据的时候,如果键是存在的,那么会把原有的键值对对象覆盖,会把覆盖的值进行返回 */Stringvalue1m.put(江户川柯南,毛利兰);System.out.println(value1);// nullm.put(黑羽快斗,中森青子);m.put(服部平次,荷叶);m.put(源源,甜甜);Stringvaluem.put(江户川柯南,灰原哀);System.out.println(value);// 毛利兰/** * 删除元素: * remove:根据键删除键值对,返回删除的值 * clear:清空集合 */Stringresultm.remove(服部平次);System.out.println(result);// 荷叶m.clear();/** * 判断是否包含: * containsKey:根据键判断元素是否存在 * containsValue:根据值判断元素是否存在 */booleankeyResultm.containsKey(源源);booleankeyResult1m.containsKey(源源6);System.out.println(keyResult);//trueSystem.out.println(keyResult1);//falsebooleankeyResult2m.containsValue(甜甜);System.out.println(keyResult2);//true/** * 判断是否为空 */m.clear();booleanresultm.isEmpty();System.out.println(result);// true/** * 获取集合的长度 * size */intsizem.size();System.out.println(size);System.out.println(m);}}‍三、Map的遍历方式键找值键值对Lambda表达式publicstaticvoidmain(String[]args){MapString,StringmapnewHashMap();map.put(江户川柯南,毛利兰);map.put(黑羽快斗,中森青子);map.put(服部平次,荷叶);map.put(源源,甜甜);// 1.键找值SetStringkeysmap.keySet();//------------------------------------------//增强forfor(Stringkey:keys){// 利用map集合中的键获取对应的值 getStringvaluemap.get(key);System.out.println(keyvalue);}//------------------------------------------//迭代器IteratorStringitkeys.iterator();while(it.hasNext()){Stringkeyit.next();Stringvaluemap.get(key);System.out.println(keyvalue);}//------------------------------------------//Lambda表达式keys.forEach(key-{Stringvaluemap.get(key);System.out.println(keyvalue);});//------------------------------------------//2.键值对//Set无序集合,不可重复SetMap.EntryString,Stringentriesmap.entrySet();for(Map.EntryString,Stringentry:entries){Stringkeyentry.getKey();Stringvalueentry.getValue();System.out.println(keyvalue);}IteratorMap.EntryString,Stringitentries.iterator();while(it.hasNext()){Map.EntryString,Stringnextit.next();Stringkeynext.getKey();Stringvaluenext.getValue();System.out.println(keyvalue);}entries.forEach(entry-{Stringkeyentry.getKey();Stringvalueentry.getValue();System.out.println(keyvalue);});//3.Lambda表达式map.forEach(newBiConsumerString,String(){Overridepublicvoidaccept(Stringkey,Stringvalue){System.out.println(keyvalue);}});map.forEach((key,value)-System.out.println(keyvalue));}‍四、HashMap1. HashMap的特点HashMap是Map里面的一个实现类没有额外需要学习的特有方法,直接使用Map里面的方法就可以了特点都是由键决定的 : 无序、不重复、无索引HashMap和HashSet底层原理是一模一样的,都是哈希表结构✏️ HashMapHashMap底层是哈希表结构的,插入键值对对象时,会用键计算哈希值,放入指定位置,与值无关依赖hashCode方法和equals方法保证键的唯一如果键存储的是自定义对象,需要重写hashCode和equals方法如果值存储自定义对象,不需要重写hashCode和equals方法publicclassStudent{privateStringname;privateIntegerage;publicStudent(){}publicStudent(Stringname,Integerage){this.namename;this.ageage;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicIntegergetAge(){returnage;}publicvoidsetAge(Integerage){this.ageage;}OverridepublicStringtoString(){returnStudent{namename\, ageage};}Overridepublicbooleanequals(Objecto){if(onull||getClass()!o.getClass())returnfalse;Studentstudent(Student)o;returnObjects.equals(name,student.name)Objects.equals(age,student.age);}OverridepublicinthashCode(){returnObjects.hash(name,age);}}publicclassHashMapDemo1{publicstaticvoidmain(String[]args){HashMapStudent,StringhmnewHashMap();Students1newStudent(源源,19);Students2newStudent(甜甜,18);Students3newStudent(柯南,17);hm.put(s1,安徽);hm.put(s2,浙江);hm.put(s3,上海);hm.put(s3,东京);// 遍历集合SetStudentstudentshm.keySet();students.forEach(s-{Stringvaluehm.get(s);System.out.println(svalue);});System.out.println(------------------------);SetMap.EntryStudent,Stringentrieshm.entrySet();entries.forEach(entry-{Studentkeyentry.getKey();Stringvalueentry.getValue();System.out.println(keyvalue);});System.out.println(--------------------------);hm.forEach((key,value)-System.out.println(keyvalue));}}‍五、LinkedHashMap1. LinkedHashMap的特点由键决定 : 有序、不重复、无索引这里的有序指的是保证存储和取出的元素顺序一致原理 : 底层数据结构是依然哈希表,只是每个键值对元素又额外多了一个双向链表的机制记录存储的顺序publicstaticvoidmain(String[]args){LinkedHashMapString,IntegerlhmnewLinkedHashMap();lhm.put(源源,1126);lhm.put(甜甜,0101);lhm.put(柯南,9568);lhm.put(灰原哀,2237);System.out.println(lhm);// {源源1126, 甜甜65, 柯南9568, 灰原哀2237} 顺序一致!!!}‍六、TreeMap1. TreeMap的特点 :TreeMap和TreeSet底层原理一样,都是红黑树结构的由键决定特性 : 不重复、无索引、可排序可排序 : 对键进行排序注意 : 默认按照键的从小到大进行排序,也可以自己规定键的排序规则‍2. 两种排序规则的书写实现Comparable接口,指定比较规则创建集合时传递Comparator比较器对象,指定比较规则 注意两中方式都书写的话,按照第二种Comparator比较器对象为准❗ 提醒Java中已经实现了Integer和Double类型的Comparable接口,默认按照升序排序的String类型按照字母在ASCII码表中对应的数字升序进行排列‍例子 :键 : 学生对象 值 : 所在城市 按照学生年龄升序排列,年龄一样按照姓名的字母排序,同姓名年龄视为同一个人publicclassStudentimplementsComparableStudent{privateStringname;privateIntegerage;publicStudent(){}publicStudent(Stringname,Integerage){this.namename;this.ageage;}publicIntegergetAge(){returnage;}publicvoidsetAge(Integerage){this.ageage;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}OverridepublicStringtoString(){returnStudent{namename\, ageage};}OverridepublicintcompareTo(Studento){intithis.getAge()-o.getAge();ii0?this.getName().compareTo(o.getName()):i;returni;}}publicclassTreeMapDemo1{publicstaticvoidmain(String[]args){TreeMapStudent,StringtmnewTreeMap();Students1newStudent(源源,19);Students2newStudent(甜甜,18);Students3newStudent(柯南,17);tm.put(s1,安徽);tm.put(s2,浙江);tm.put(s3,东京);System.out.println(tm);// {Student{name柯南, age17}东京, Student{name甜甜, age18}浙江, Student{name源源, age19}安徽}}}‍七、总结集合底层结构键特点使用场景HashMap哈希表无序、不重复大多数日常存储查询首选LinkedHashMap哈希表 双向链表存取有序、不重复需要保证存入顺序TreeMap红黑树按键排序、不重复需要对键自动排序‍Map 为什么键不能重复底层添加元素时先判断哈希值再 equals 比较相同则覆盖 value。‍为什么自定义对象做 key 必须重写 hashCode 和 equals‍Object 原生 hashCode 根据内存地址内容相同不同对象哈希值不一样会判定为两个 key。‍TreeMap 键对象如果不实现比较规则会报错ClassCastException