11.集合之map

本文深入解析Java中Map接口的各种实现类,包括HashMap、LinkedHashMap、TreeMap、Properties、Hashtable的特性与应用场景,以及它们之间的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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实现类的性能分析

  1. HashMap以哈希算法存储,存储无序的,通过键获取值速度最快;最长用
  2. LinkedHashMap以双向链表式存储,会按照存储的顺序存放到集合容器中,因为还要记录存储顺序所以效率低,但是遍历集合效率高
  3. properties集合也是以键值对形式存储,一般用于配置文件,比如log4j配置
  4. TreeMap以红黑树算法存储,存储的是会按照排序后再去存储集合容器中,排序方式有自然排序和定制排序
  5. HashTable和HashMap一样的存储方式,Hashtable考虑线程安全,查询效率上HashMap要更快
  6. 如果记不住,学会HashMap即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值