map接口下的集合
- map接口下的集合采用键值对Map<k,v>的存储方式,保存具有映射关系的数据。因此map集合里保存两组值,一组用于保存map里的key值,另外一组用于保存map里的value值,key和value可以是任意引用类型的数据。key值不允许重复,键可以为null,如果添加key-value键值对时已经有重复的key,则添加的value会覆盖key原来对应的value值.常用的实现类有HashMap、LinkedHashMap、TreeMap等。
- HashMap是以hash算法存储的,无序的
- LinkedHashMap是以链表方式存储的.有序的
- TreeMap是红黑树算法存储的map,有序的
1 HashMap
-
案例1:存值
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class Test { public static void main(String[] args) { Map<String,String> map = new HashMap<String,String>(); map.put("CN","中华人民共和国"); map.put("FN", "法国人民共和国"); map.put("JP","日本人民共和国"); map.put("YL", "伊朗人民共和国"); map.put(null, "伊朗人民共和国");//键可以为null map.put("CN", "大秦帝国");//键如果重复,会将后面的值覆盖前面的值 String value = map.get("CN"); System.out.println("CN键对应的值:"+value); System.out.println("是否有CN这个键:"+map.containsKey("CN")); System.out.println(map.keySet()); System.out.println(map.values()); System.out.println(map); //获取到所有的键,是一个无序的set集合 Set<String> keys = map.keySet(); //创建迭代器,让无序的键排队 Iterator<String> it = keys.iterator(); while(it.hasNext()) { //判断迭代器容器里面有没有键,如果有就取到下一个键 String key = it.next(); //根据键获取值 String value1 = map.get(key); System.out.println("值"+value1); } } }
-
结果
CN键对应的值:大秦帝国 是否有CN这个键:true [null, YL, JP, FN, CN] [伊朗人民共和国, 伊朗人民共和国, 日本人民共和国, 法国人民共和国, 大秦帝国] {null=伊朗人民共和国, YL=伊朗人民共和国, JP=日本人民共和国, FN=法国人民共和国, CN=大秦帝国} 值伊朗人民共和国 值伊朗人民共和国 值日本人民共和国 值法国人民共和国 值大秦帝国
-
案例2:存对象
-
Student类
public class Student{ private String name; private int age; public void showStudent(){ System.out.println("你好我是"+name+",年龄是:"+age); } public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
-
测试
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class Test1 { public static void main(String[] args) { Student stu1 = new Student("马云",45); Student stu2 = new Student("马化腾",40); Student stu3 = new Student("董明珠",47); Student stu4 = new Student("章泽天",28); //Map集合的适用场景:不适用于大量有序的数据遍历,一般适用于少量数据作为方法的参数 Map<String,Student> map = new HashMap<String,Student>(); map.put(stu1.getName(), stu1); map.put(stu2.getName(), stu2); map.put(stu3.getName(), stu3); map.put(stu4.getName(), stu4); //获取到所有的键,是一个无序的set集合 Set<String> keys = map.keySet(); //创建迭代器,让无序的键排队 Iterator<String> it = keys.iterator(); while(it.hasNext()) { //判断迭代器容器里面有没有键,如果有就取到下一个键 String key = it.next(); //根据键获取值 Student student = map.get(key); student.showStudent(); } System.out.println("================================="); for (String key : keys) { Student student = map.get(key); student.showStudent(); } System.out.println("==============================="); for (Student student : map.values()) { student.showStudent(); } } }
-
结果
你好我是马云,年龄是:45 你好我是章泽天,年龄是:28 你好我是董明珠,年龄是:47 你好我是马化腾,年龄是:40 ================================= 你好我是马云,年龄是:45 你好我是章泽天,年龄是:28 你好我是董明珠,年龄是:47 你好我是马化腾,年龄是:40 =============================== 你好我是马云,年龄是:45 你好我是章泽天,年龄是:28 你好我是董明珠,年龄是:47 你好我是马化腾,年龄是:40
-
2 LinkedHashMap
-
LinkedHashMap以map接口的哈希表算法和连接列表实现,具有顺序的map
-
采用双向列表来维护key-value对的次序(其实只要考虑key的次序即可),该链表负责维护map的迭代顺序,与插入顺序一致,因此性能比HashMap低,但在迭代map里的全部元素时有较好的性能
-
案例1:
import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; public class Test { public static void main(String[] args) { //LinkedHashMap以双向链表式按照你插入元素的顺序放到LinkedHashMap容器中 //插入性能低,按键取值性能比hashMap低,但是遍历所有值的时候效率高 Map<String,String> map = new LinkedHashMap<String,String>(); map.put("CN","中华人民共和国"); map.put("FN", "法国人民共和国"); map.put("JP","日本人民共和国"); map.put("YL", "伊朗人民共和国"); map.put(null, "伊朗人民共和国");//键可以为null map.put("CN", "大秦帝国");//键如果重复,会将后面的值覆盖前面的值 String value = map.get("CN"); System.out.println("CN键对应的值:"+value); System.out.println("是否有CN这个键:"+map.containsKey("CN")); System.out.println(map.keySet()); System.out.println(map.values()); System.out.println(map); //获取到所有的键,是一个无序的set集合 Set<String> keys = map.keySet(); //创建迭代器,让无序的键排队 Iterator<String> it = keys.iterator(); while(it.hasNext()) { //判断迭代器容器里面有没有键,如果有就取到下一个键 String key = it.next(); //根据键获取值 String value1 = map.get(key); System.out.println("值"+value1); } } }
-
结果
CN键对应的值:大秦帝国 是否有CN这个键:true [CN, FN, JP, YL, null] [大秦帝国, 法国人民共和国, 日本人民共和国, 伊朗人民共和国, 伊朗人民共和国] {CN=大秦帝国, FN=法国人民共和国, JP=日本人民共和国, YL=伊朗人民共和国, null=伊朗人民共和国} 值大秦帝国 值法国人民共和国 值日本人民共和国 值伊朗人民共和国 值伊朗人民共和国
-
案例2:存对象
import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; public class Test1 { public static void main(String[] args) { Student stu1 = new Student("马云",45); Student stu2 = new Student("马化腾",40); Student stu3 = new Student("董明珠",47); Student stu4 = new Student("章泽天",28); //Map集合的适用场景:不适用于大量有序的数据遍历,一般适用于少量数据作为方法的参数 Map<String,Student> map = new LinkedHashMap<String,Student>(); map.put(stu1.getName(), stu1); map.put(stu2.getName(), stu2); map.put(stu3.getName(), stu3); map.put(stu4.getName(), stu4); //获取到所有的键,是一个无序的set集合 Set<String> keys = map.keySet(); //创建迭代器,让无序的键排队 Iterator<String> it = keys.iterator(); while(it.hasNext()) { //判断迭代器容器里面有没有键,如果有就取到下一个键 String key = it.next(); //根据键获取值 Student student = map.get(key); student.showStudent(); } System.out.println("================================="); for (String key : keys) { Student student = map.get(key); student.showStudent(); } System.out.println("==============================="); for (Student student : map.values()) { student.showStudent(); } } }
-
结果
你好我是马云,年龄是:45 你好我是马化腾,年龄是:40 你好我是董明珠,年龄是:47 你好我是章泽天,年龄是:28 ================================= 你好我是马云,年龄是:45 你好我是马化腾,年龄是:40 你好我是董明珠,年龄是:47 你好我是章泽天,年龄是:28 =============================== 你好我是马云,年龄是:45 你好我是马化腾,年龄是:40 你好我是董明珠,年龄是:47 你好我是章泽天,年龄是:28 10
3 Properties
Properties类是HashTable的子类,它相当于一个key、value都是String类型的map,主要用于读取配置文件,比如之前学的log4j.properties配置文件,将系统的配置信息配置在该文件中。
4 TreeMap
-
基于红黑树算法实现,非线程安全,不允许null,key不允许重复,它是sortedMap的实现类,会根据红黑树算法将key排序后插入到TreeMap容器中。也可以采取自然排序和自定义排序。
-
如果采用自定义排序,可以实现compareable接口或者comparator接口来重写comparaTo方法来自定义排序
-
案例
import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; public class Test { public static void main(String[] args) { //TreeMap是会排序后插入到容器中(LinkedHashMap是按序插入) //默认是自然排序,如果需要按照你的规则,需要实现comparator接口重写排序规则 Map<String,String> map = new TreeMap<String,String>(); map.put("CN", "中国"); map.put("AN", "美国"); map.put("YL", "伊朗"); map.put("JP", "日国"); //获取到所有的键,是一个无序的set集合 Set<String> keys = map.keySet(); //创建迭代器,让无序的键排队 Iterator<String> it = keys.iterator(); while(it.hasNext()) { //判断迭代器容器里面有没有键,如果有就取到下一个键 String key = it.next(); //根据键获取值 String value1 = map.get(key); System.out.println("值"+value1); } } }
-
结果
值美国 值中国 值日国 值伊朗
5 Hashtable
Hashtable与HashMap的区别
-
hashMap是非线程安全的,hashtable是线程安全的,效率上低于hashMap
-
案例
-
Student类
public class Student{ private String name; private int age; public void showStudent(){ System.out.println("你好我是"+name+",年龄是:"+age); } public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
-
测试类
import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Set; public class Test1 { public static void main(String[] args) { Student stu1 = new Student("马云",45); Student stu2 = new Student("马化腾",40); Student stu3 = new Student("董明珠",47); Student stu4 = new Student("章泽天",28); //hashMap是非线程安全的,hashtable是线程安全的,效率上低于hashMap Map<String,Student> map = new Hashtable<String,Student>(); map.put(stu1.getName(), stu1); map.put(stu2.getName(), stu2); map.put(stu3.getName(), stu3); map.put(stu4.getName(), stu4); //获取到所有的键,是一个无序的set集合 Set<String> keys = map.keySet(); //创建迭代器,让无序的键排队 Iterator<String> it = keys.iterator(); while(it.hasNext()) { //判断迭代器容器里面有没有键,如果有就取到下一个键 String key = it.next(); //根据键获取值 Student student = map.get(key); student.showStudent(); } System.out.println("================================="); for (String key : keys) { Student student = map.get(key); student.showStudent(); } System.out.println("==============================="); for (Student student : map.values()) { student.showStudent(); } } }
-
结果
你好我是马云,年龄是:45 你好我是章泽天,年龄是:28 你好我是马化腾,年龄是:40 你好我是董明珠,年龄是:47
6 各Map实现类的性能分析
- HashMap以哈希算法存储,存储无序的,通过键获取值速度最快;最长用
- LinkedHashMap以双向链表式存储,会按照存储的顺序存放到集合容器中,因为还要记录存储顺序所以效率低,但是遍历集合效率高
- properties集合也是以键值对形式存储,一般用于配置文件,比如log4j配置
- TreeMap以红黑树算法存储,存储的是会按照排序后再去存储集合容器中,排序方式有自然排序和定制排序
- HashTable和HashMap一样的存储方式,Hashtable考虑线程安全,查询效率上HashMap要更快
- 如果记不住,学会HashMap即可