简单看下Map的场景

如果程序中存储了几百万个学生,而且经常需要使用学号来搜索某个学生,那么这个需求有效的数据结构就是Map。

Map是一种依照键(key)存储元素的容器,键(key)很像下标,在List中下标是整数。

在Map中键(key)可以使任意类型的对象。

Map中不能有重复的键(Key),每个键(key)都有一个对应的值(value)。

一个键(key)和它对应的值构成map集合中的一个元素。

Map中的元素是两个对象,一个对象作为键,一个对象作为值。键不可以重复,但是值可以重复。

看顶层共性方法找子类特有对象.

Map与Collection在集合框架中属并列存在

Map存储的是键值对

Map存储元素使用put()方法,Collection使用add()方法

Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素

Map集合中键要保证唯一性

也就是Collection是单列集合, Map 是双列集合。

总结:

Map一次存一对元素, Collection 一次存一个。

Map 的键不能重复,保证唯一。

Map 一次存入一对元素,是以键值对的形式存在.键与值存在映射关系.一定要保证键的唯一性.

查看api文档:

  1. interface Map<K,V>
  2. K - 此映射所维护的键的类型
  3. V - 映射值的类型

概念

将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

特点

Key和Value是1对1的关系,如:门牌号 :家 老公:老婆

双列集合

Map体系

  1. | Map 接口 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
  2. ---|Hashtable:
  3. 底层是哈希表数据结构,线程是同步的,不可以存入null键,null值。
  4. 效率较低,被HashMap 替代。
  5. ---|HashMap:
  6. 采用哈希表实现,所以无序。
  7. 底层是哈希表数据结构,线程是不同步的,可以存入null键,null值。
  8. 要保证键的唯一性,需要覆盖hashCode方法,和equals方法。
  9. ---| LinkedHashMap
  10. 该子类基于哈希表又融入了链表。可以Map集合进行增删提高效率。
  11. ---|TreeMap:
  12. 底层是二叉树数据结构,可以对健进行排序。
  13. 可以对map集合中的键进行排序。
  14. 需要使用Comparable或者Comparator 进行比较排序。
  15. return 0,来判断键的唯一性。

常见方法

  1. 1、添加:
  2. put(K key, V value) (可以相同的key值,但是添加的value值会覆盖前面的,返回值是前一个,如果没有就返回null
  3. putAll(Map<? extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中(可选操作)。
  4. 2、删除
  5. remove() 删除关联对象,指定key对象
  6. clear() 清空集合对象
  7. 3、获取
  8. value get(key); 可以用于判断键是否存在的情况。当指定的键不存在的时候,返回的是null
  9. 4、判断:
  10. boolean isEmpty() 长度为0返回true否则false
  11. boolean containsKey(Object key) 判断集合中是否包含指定的key
  12. boolean containsValue(Object value) 判断集合中是否包含指定的value
  13. int size()获取长度

基本操作案例:

  1. // Map集合包
  2. import java.util.Map;
  3. import java.util.HashMap;
  4. public class HelloWorld{
  5. // 入口
  6. public static void main(String[] agrs) {
  7. //---------------------- 新增 ----------------------
  8. // 定义一个Map的容器对象
  9. Map map1 = new HashMap();
  10. // 添加重复的键值(值不同),会返回最后覆盖的值
  11. map1.put("jack", 20);
  12. map1.put("rose", 18);
  13. map1.put("lucy", 17);
  14. map1.put("jack", 25);
  15. System.out.println(map1);
  16. // 定义一个Map的容器对象
  17. Map map2= new HashMap();
  18. map2.put("张三丰", 100);
  19. map2.put("虚竹", 20);
  20. // 从指定映射中将所有映射关系复制到此映射中。
  21. map1.putAll(map2);
  22. System.out.println(map1);
  23. //---------------------- 删除 ----------------------
  24. // 指定key删除,返回删除的键值对映射的值。
  25. System.out.println("value:" + map1.remove("jack"));
  26. // 直接整个清空
  27. map2.clear();
  28. System.out.println("map2:" + map2);
  29. //---------------------- 获取 ----------------------
  30. // 指定key读取
  31. System.out.println("value:" + map1.get("虚竹"));
  32. // 获取长度
  33. System.out.println("map1长度:" + map1.size());
  34. //---------------------- 判断 ----------------------
  35. // 是否空Map
  36. System.out.println("Map1是否空:" + map1.isEmpty());
  37. // 键是否存在
  38. System.out.println("Map1键是否存在:" + map1.containsKey("jack"));
  39. // 值是否存在
  40. System.out.println("Map1值是否存在:" + map1.containsValue(100));
  41. }
  42. }

1.HashMap

遍历读取Map

Map的遍历读取主要有三种方法:

  1. 1、将map 集合中所有的键取出存入set集合。
  2. keySet() 返回所有的key对象的Set集合,再通过get方法获取键对应的值。
  3. 2values() 获取所有的值,不能获取到key对象
  4. 3Map.Entry对象【推荐使用,重点】
  5. entrySet() map 集合中的键值映射关系打包成一个对象。
  6. Map.Entry对象通过Map.Entry对象的getKeygetValue获取其键和值。

第一种遍历方法:keySet()

将Map转成Set集合keySet(),通过Set的迭代器取出Set集合中的每一个元素(Iterator)就是Map集合中的所有的键,再通过get方法获取键对应的值。

  1. // Map集合包
  2. import java.util.Map;
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. import java.util.Set;
  6. public class HelloWorld{
  7. // 入口
  8. public static void main(String[] agrs) {
  9. // 定义一个Map的容器对象
  10. Map map = new HashMap();
  11. // 添加重复的键值(值不同),会返回最后覆盖的值
  12. map.put("jack", 20);
  13. map.put("rose", 18);
  14. map.put("lucy", 17);
  15. map.put("java", 25);
  16. // 先转Set
  17. Set<String> ks = map.keySet();
  18. Iterator<String> it = ks.iterator();
  19. // 不为空
  20. while (it.hasNext()) {
  21. // 获取key
  22. String key = it.next();
  23. // 因为不知道value的类型,所以用obj是通用
  24. Object value = map.get(key);
  25. // 也可以强行转成自己知道的类型
  26. //Integer value = (Integer) map.get(key);
  27. System.out.println(key+":"+value);
  28. }
  29. }
  30. }

第二种遍历方法: 通过values(),获取所有值,不能获取到key对象

  1. // Map集合包
  2. import java.util.Collection;
  3. import java.util.Map;
  4. import java.util.HashMap;
  5. import java.util.Iterator;
  6. public class HelloWorld{
  7. // 入口
  8. public static void main(String[] agrs) {
  9. // 定义一个Map的容器对象
  10. Map map = new HashMap();
  11. // 添加重复的键值(值不同),会返回最后覆盖的值
  12. map.put("jack", 20);
  13. map.put("rose", 18);
  14. map.put("lucy", 17);
  15. map.put("java", 25);
  16. Collection vs = map.values();
  17. Iterator<Integer> it = vs.iterator();
  18. // 有内容
  19. while(it.hasNext()){
  20. // 拿Value
  21. Integer value = it.next();
  22. System.out.println(+value);
  23. }
  24. }
  25. }

第三种遍历方法:Map.Entry()

  1. // Map集合包
  2. import java.util.Map;
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. public class HelloWorld{
  6. // 入口
  7. public static void main(String[] agrs) {
  8. // 定义一个Map的容器对象
  9. Map map = new HashMap();
  10. // 添加重复的键值(值不同),会返回最后覆盖的值
  11. map.put("jack", 20);
  12. map.put("rose", 18);
  13. map.put("lucy", 17);
  14. map.put("java", 25);
  15. // 转Set
  16. Iterator<Map.Entry> entries = map.entrySet().iterator();
  17. // 有内容
  18. while(entries.hasNext()){
  19. // 拿当前的
  20. Map.Entry<String, Integer> entry = entries.next();
  21. // 拿Key
  22. String key = entry.getKey();
  23. // 拿Value
  24. Integer value = entry.getValue();
  25. System.out.println(key+':'+value);
  26. }
  27. }
  28. }

最后一个常用的遍历方法:

  1. // Map集合包
  2. import java.util.Map;
  3. import java.util.HashMap;
  4. public class HelloWorld{
  5. // 入口
  6. public static void main(String[] agrs) {
  7. // 定义一个Map的容器对象
  8. Map<String, Integer> map = new HashMap();
  9. map.put("jack", 20);
  10. map.put("rose", 18);
  11. map.put("lucy", 17);
  12. map.put("java", 25);
  13. // 上面的Map类型必须定义,不然找不到Map类型
  14. for(Map.Entry<String, Integer> entry : map.entrySet()){
  15. // 拿key
  16. String key = entry.getKey();
  17. // 拿value
  18. Integer value = entry.getValue();
  19. System.out.println(key+":"+value);
  20. }
  21. }
  22. }

2.TreeMap

TreeMap的排序,TreeMap可以对集合中的键进行排序。

如何实现键的排序?

方式一:元素自身具备比较性

和TreeSet一样原理,需要让存储在键位置的对象实现Comparable接口,重写compareTo方法,也就是让元素自身具备比较性,这种方式叫做元素的自然排序也叫做默认排序。

方式二:容器具备比较性

当元素自身不具备比较性,或者自身具备的比较性不是所需要的。

那么此时可以让容器自身具备。

需要定义一个类实现接口Comparator,重写compare方法,并将该接口的子类实例对象作为参数传递给TreeMap集合的构造方法。

注意:当Comparable比较方式和Comparator比较方式同时存在时,以Comparator的比较方式为主;

注意:在重写compareTo或者compare方法时,必须要明确比较的主要条件相等时要比较次要条件。

(假设姓名和年龄一直的人为相同的人,如果想要对人按照年龄的大小来排序,如果年龄相同的人,需要如何处理?不能直接return 0,以为可能姓名不同(年龄相同姓名不同的人是不同的人)。此时就需要进行次要条件判断(需要判断姓名),只有姓名和年龄同时相等的才可以返回0.)

通过return 0来判断唯一性。

基本操作汇总

  1. import java.util.Collection;
  2. import java.util.Map;
  3. import java.util.Set;
  4. import java.util.SortedMap;
  5. import java.util.TreeMap;
  6. public class HelloWorld{
  7. // 入口
  8. public static void main(String[] agrs) {
  9. //创建TreeMap对象:
  10. TreeMap<String,Integer> treeMap = new TreeMap<String,Integer>();
  11. System.out.println("初始化后,TreeMap元素个数为:" + treeMap.size());
  12. //新增元素:
  13. treeMap.put("hello",1);
  14. treeMap.put("world",2);
  15. treeMap.put("my",3);
  16. treeMap.put("name",4);
  17. treeMap.put("is",5);
  18. treeMap.put("jiaboyan",6);
  19. treeMap.put("i",6);
  20. treeMap.put("am",6);
  21. treeMap.put("a",6);
  22. treeMap.put("developer",6);
  23. System.out.println("添加元素后,TreeMap元素个数为:" + treeMap.size());
  24. //遍历元素:
  25. Set<Map.Entry<String,Integer>> entrySet = treeMap.entrySet();
  26. for(Map.Entry<String,Integer> entry : entrySet){
  27. String key = entry.getKey();
  28. Integer value = entry.getValue();
  29. System.out.println("TreeMap元素的key:"+key+",value:"+value);
  30. }
  31. //获取所有的key:
  32. Set<String> keySet = treeMap.keySet();
  33. for(String strKey:keySet){
  34. System.out.println("TreeMap集合中的key:"+strKey);
  35. }
  36. //获取所有的value:
  37. Collection<Integer> valueList = treeMap.values();
  38. for(Integer intValue:valueList){
  39. System.out.println("TreeMap集合中的value:" + intValue);
  40. }
  41. //获取元素:
  42. Integer getValue = treeMap.get("jiaboyan");//获取集合内元素key为"jiaboyan"的值
  43. String firstKey = treeMap.firstKey();//获取集合内第一个元素
  44. String lastKey =treeMap.lastKey();//获取集合内最后一个元素
  45. String lowerKey =treeMap.lowerKey("jiaboyan");//获取集合内的key小于"jiaboyan"的key
  46. String ceilingKey =treeMap.ceilingKey("jiaboyan");//获取集合内的key大于等于"jiaboyan"的key
  47. SortedMap<String,Integer> sortedMap =treeMap.subMap("a","my");//获取集合的key从"a"到"jiaboyan"的元素
  48. //删除元素:
  49. Integer removeValue = treeMap.remove("jiaboyan");//删除集合中key为"jiaboyan"的元素
  50. treeMap.clear(); //清空集合元素:
  51. //判断方法:
  52. boolean isEmpty = treeMap.isEmpty();//判断集合是否为空
  53. boolean isContain = treeMap.containsKey("jiaboyan");//判断集合的key中是否包含"jiaboyan"
  54. }
  55. }

使用元素自然排序

  1. import java.util.TreeMap;
  2. public class HelloWorld{
  3. // 入口
  4. public static void main(String[] agrs) {
  5. TreeMap<Integer,String> treeMap = new TreeMap<Integer, String>();
  6. treeMap.put(1,"jiaboyan");
  7. treeMap.put(6,"jiaboyan");
  8. treeMap.put(3,"jiaboyan");
  9. treeMap.put(10,"jiaboyan");
  10. treeMap.put(7,"jiaboyan");
  11. treeMap.put(13,"jiaboyan");
  12. System.out.println(treeMap.toString());
  13. }
  14. }

使用自定义比较器排序

  1. import java.util.Comparator;
  2. import java.util.TreeMap;
  3. class SortedTest {
  4. private int age;
  5. public SortedTest(int age){
  6. this.age = age;
  7. }
  8. public int getAge() {
  9. return age;
  10. }
  11. public void setAge(int age) {
  12. this.age = age;
  13. }
  14. }
  15. class SortedTestComparator implements Comparator<SortedTest> {
  16. //自定义比较器:实现compare(T o1,T o2)方法:
  17. public int compare(SortedTest sortedTest1, SortedTest sortedTest2) {
  18. int num = sortedTest1.getAge() - sortedTest2.getAge();
  19. if(num==0){//为0时候,两者相同:
  20. return 0;
  21. }else if(num>0){//大于0时,后面的参数小:
  22. return 1;
  23. }else{//小于0时,前面的参数小:
  24. return -1;
  25. }
  26. }
  27. }
  28. public class HelloWorld {
  29. public static void main(String[] agrs){
  30. //自定义顺序比较
  31. customSort();
  32. }
  33. //自定义排序顺序:
  34. public static void customSort(){
  35. TreeMap<SortedTest,String> treeMap = new TreeMap<SortedTest, String>(new SortedTestComparator());
  36. treeMap.put(new SortedTest(10),"hello");
  37. treeMap.put(new SortedTest(21),"my");
  38. treeMap.put(new SortedTest(15),"name");
  39. treeMap.put(new SortedTest(2),"is");
  40. treeMap.put(new SortedTest(1),"jiaboyan");
  41. treeMap.put(new SortedTest(7),"world");
  42. System.out.println(treeMap.toString());
  43. }
  44. }

这个自定义排序太难了,说实在的我也没搞明白,以后有收获再回头补上吧