1 什么是map集合?
我认为map集合的使用了存储具有那种对应关系的对象的集合。根据Interface Map<K,V> K钥匙的Map保持型 V 映射的值的类型,集合中存储了两个属性,一个是key一个是value,也就是键值对的关系,找到键就可以相应的值,就类似学生的学号,我们的身份证,都是和我一一对应的。 其实这个也可以和collection集合做个比较: 图:
1.1 Map集合中常用的子类:
AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, Hashtable, IdentityHashMap, LinkedHashMap, PrinterStateReasons, Properties, Provider, RenderingHints, SimpleBindings, TabularDataSupport, TreeMap, UIDefaults, WeakHashMap
- HashMap:
底层是hash表组成(数组+链表的结构的,在jdk1.8之后是数组+链表/红黑树),元素的存取的顺序不一样,无序集合。在自定义数据类型的时候,为了保证数据的唯一性,必须重写Hashcode()和equals方法,保证key的唯一性
- LinkHashMap:
同样底层是hash表+链表的结构,因为多加了一条链表,就可以保证存储数据的顺序,有序集合,也就是通过重写了Hashcode()和equals方法 实现了数据的唯一性。
1.2 Map集合中常用方法
api文档:
-
public v put (K key,V value);将指定的值与此映射中的指定键关联(可选操作)。
-
public v remove(Object key); 如果存在(可选操作),则从该Map中移除一个键的映射。
-
public V get(Object key) 根据指定的键,在Map集合中获取对应的值。(value)
-
public Set keySet() : 获取Map集合中所有的键,存储到Set集合中。
-
public boolean containsKey(Object key) /containsValue(Object value)
-
public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合);判断集合中是否存储value或者key,多判断key。
-
代码如下:
private static void showPutMethod() { /** * put语法规则 * 首次添加元素的时候,如果k的值是不重复的 则会返回一个null * 如果添加重复k的值 则第二次添加的v的值会把第一次v的值替换的 返回的是被替换的数值 * k是不允许重复的 而value是可以重复的 */ Map<String, String> map = new HashMap<>(); String put = map.put("zsb", "张博阳"); String put1 = map.put("zsb", "昔年"); String put2 = map.put("dsa", "褐瞳"); String put3 = map.put("ewqe", "心塞"); String put4 = map.put("zsgf", "昔年"); System.out.println(map); } /** * remove(object k)指定k 返回v * 存在则有返回值 * 不存在 返回null */ private static void removeTestMethod() { Map<String, Integer> map = new HashMap<>(); // String person = map.put("海绵宝宝", "100"); // String person2 = map.put("派大星", "230"); // String person3 = map.put("章鱼哥", "321"); // String person4 = map.put("蟹老板", "456"); // String one = map.remove("海绵宝宝"); // System.out.println(one);//返回100 //返回null Integer dsada = map.remove("dsada"); System.out.println(dsada);//null } /** * get语法规则 输入数值 返回键的关系 * 有键返回值数值 * 没有键 返回空 * */ //map集合存储 Map<String, String> mapList = new HashMap<>(); String put = mapList.put("zsb", "一品御前带刀侍卫"); System.out.println(put); mapList.put("派大星","赤犬星"); mapList.put("海绵宝宝","黄袁宝宝"); mapList.put("章鱼哥","青雉鱼"); mapList.put("zsb","酷酷的张博阳"); //get方法 String zz = mapList.get("章鱼哥"); System.out.println(zz); // 返回青雉鱼 System.out.println(mapList); /** * containsKey * 查询集合中是否包含该元素 * 如果有 true * 没有 false */ private static void containsMethod(){ Map<String, String> map = new HashMap<>(); String one = map.put("zsb", "保安队长"); String two = map.put("zsb", "保安"); String three = map.put("zsbaa", "保安"); String four = map.put("zsbss", "保安"); boolean zbs = map.containsKey("zsb"); boolean zbs1 = map.containsKey("zdsadbs"); // System.out.println(zbs);//true // System.out.println(zbs1);// false 复制代码
1.3 Hashmap集合的遍历方法
方法一:
通过keyset方法把Map集合转换成Set集合,然后我们就可以对Set集合进行循环遍历,可以使用增强for循环的方式,也可以使用迭代器的方式进行循环遍历。在我们循环遍历之后,我们拿到了key的数值,然后通过Map的get方法 然后可以获得集合中的value方法:如图所示
代码如下:
Map<String, String> mapList = new HashMap<>();
String put = mapList.put("zsb", "一品御前带刀侍卫");
System.out.println(put);
mapList.put("派大星","赤犬星");
mapList.put("海绵宝宝","黄袁宝宝");
mapList.put("章鱼哥","青雉鱼");
mapList.put("zsb","酷酷的张博阳");
//利用增强for循环
/**
* 通过keyset方法把 map集合里面的key的值存储打set集合里面,然后遍历set集合,即可得到key的数值,然后通过map的
* get方法 通过key获得value 然后就完成了遍历
*/
Set<String> setList = mapList.keySet();
for (String s : setList) {// 这里可以直接写 :mapList.keySet();
//现在拿到集合里面的value的数值了 然后通过map.get的方法 获得里面的数值
String value = mapList.get(s);
System.out.println(value);
}
//利用迭代器进行循环遍历
System.out.println("-----------------");
Iterator<String> iteratorSet = setList.iterator();
while (iteratorSet.hasNext()) {
String next = iteratorSet.next();
String value2 = mapList.get(next);
System.out.println(value2);
}
复制代码
方法2 通过他的内部嵌套类(entry)进行调用
当Map集合创建的时候,就自动创建了Entry对象,用来记录键和值的关系。 我们可以通过Map.entrySet方法把Map集合中的多个Entry对象取出来存储到set集合中 ,剩下的就和上面一样通过循环的方式进行遍历,但是Entry接口,他自己有两个方法分别是getkey和 getValue方法 然后分别获取键和值。 代码如下:
public static void main(String[] args) {
Map<String, String> mapList = new HashMap<>();
String put = mapList.put("zsb", "一品御前带刀侍卫");
mapList.put("派大星","赤犬星");
mapList.put("海绵宝宝","黄袁宝宝");
mapList.put("章鱼哥","青雉鱼");
mapList.put("zsb","酷酷的张博阳");
//增强for循环的方式
for (Map.Entry<String, String> entryList :mapList.entrySet()){
String key = entryList.getKey();
String value = entryList.getValue();
System.out.println(key + value);
}
//利用迭代器方式
Set<Map.Entry<String, String>> entries = mapList.entrySet();
Iterator<Map.Entry<String, String>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> next = iterator.next();
String key = next.getKey();//分别获取到key的数值
String value = next.getValue();//分别获得value的数值
System.out.println(key + value);
}
}
//同样是for循环为什么这个entry不能同Map.get()方法获得value值,把获得next穿进去,为什么返回值是null
//我探究了一下 之前的Map集合创建了set对象 里面存储的是key的集合,当然可以用get方法传递key获得value
//而entry就不同了,集合里面存储的是循环遍历之后的entry对象,又不是key当然获取不出来了。
复制代码
自定义数据类型
如果自定义数据类型作为键的话,一定要重写里面的getCode和equals方法保证键的唯一性
代码如下: 自定义数据类型:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
People people = (People) o;
return age == people.age &&
Objects.equals(name, people.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
主方法如下:
public static void main(String[] args) {
getMethod();
getMethod2();
}
private static void getMethod(){
HashMap<People, String> peopleStringHashMap = new HashMap<>();
peopleStringHashMap.put(new People("海绵宝宝",20),"蟹黄堡厨师");
peopleStringHashMap.put(new People("派大星",20),"海绵宝宝最好的朋友");
peopleStringHashMap.put(new People("章鱼哥",30),"蟹黄包的收银员");
//遍历集合
for (People people : peopleStringHashMap.keySet()) {
String value = peopleStringHashMap.get(people);
System.out.println(value);
}
}
private static void getMethod2() {
HashMap<People, String> peopleStringHashMap = new HashMap<>();
peopleStringHashMap.put(new People("海绵宝宝",20),"蟹黄堡厨师");
peopleStringHashMap.put(new People("派大星",20),"海绵宝宝最好的朋友");
peopleStringHashMap.put(new People("章鱼哥",30),"蟹黄包的收银员");
//通过创建entry对象的方式
Set<Map.Entry<People, String>> entries = peopleStringHashMap.entrySet();
//创建迭代器
Iterator<Map.Entry<People, String>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<People, String> entry = iterator.next();
People key = entry.getKey();
String value = entry.getValue();
System.out.println(key + value);
}
}
复制代码
1.3 linkHashMap和linkHashtable
- linkHashMap相比HashMap集合就是多了一个link然后可以保证存取顺序,这点是最大的区别
- 而linkHashtable 底层是一个哈希表,是单线程的速度较慢,集合不能存储null建和值(在1.2之后被hashMap取代)