Map(HashMap、LinkedHashMap、TreeMap)

 * 面试题:
 Map和Collection集合的区别?
 * 	Collection集合只能存储一种类型的元素,----->理解为 "单身"	11.11	光棍
 * 			Collection集合的Set的子实现类 hashSet,TreeSet和Map有关系
 * 	Map集合:存储的是键值对,一个键对应一个值(值是可以重复的),针对键有效,跟值无关!		理解为("夫妻对")
 * 			HashMap,TreeMap

map

什么是Map。在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value。这就是我们平时说的键值对。
通过键----->查询值
Map集合的特点,存储的键值对(键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。)

 键如果在Map出现第一次,返回值null,如果键重复了,后面出现的值会将前面的值覆盖掉,返回结果是以前的值
//System.out.println("put():"+map.put("文章","马伊琍")) ;
//System.out.println("put():"+map.put("文章","姚笛")) ;//put():马伊琍
	Map<String, String> map = new HashMap<String, String>();
		map.put("邓超", "孙俪") ;
		map.put("周杰伦", "昆凌") ;
		map.put("刘恺威", "杨幂") ;
		
		//删除
		// V remove(Object key) :删除指定的键
		System.out.println("remove():"+map.remove("邓超"));// remove():孙俪 //返回当前键对应的值 
//		map.clear();  //暴力删除 (慎用)// {}
		
		//判断功能
		//boolean containsKey(Object key)   :判断是否包含指定的键
		System.out.println("containsKey():"+map.containsKey("文章"));
		System.out.println("containsKey():"+map.containsKey("高圆圆"));
		//是否包含值 //containsKey():false //containsKey():true
		//boolean isEmpty():判断集合是否为空
		System.out.println("isEmpty():"+map.isEmpty());//isEmpty():false
		
		//public int size():
		System.out.println("size():"+map.size());//size():3
		//get(Object key) :根据键获取值
		System.out.println("get():"+map.get("周杰伦"));//get():昆凌
		System.out.println("get():"+map.get("文章")); //不存在键返回null  //get():null
		//输出Map集合
		System.out.println("map:"+map); //{邓超=孙俪, 周杰伦=昆凌, 高圆圆=赵又廷, 刘恺威=杨幂}
	}
	
//map集合遍历方法(两种)
	
	Map<String,String>  map = new HashMap<String,String>();
        map.put("02","zhangsan2");
        map.put("03", "zhangsan3");
        map.put("01", "zhangsan1");
        map.put("04", "zhangsan4");
       //	第一种:(推荐)Set<K> keySet() :获取所有的键的集合 
        //先获取map集合的所有键的set集合,keySet()---->get()方法获取对应键的值;
		//Set<String>相当于返回值类型,此相当于Set集合加上了泛型,类型为String,set相当于变量名
		Set<String> set = map.keySet() ;
		//增强for遍历
		for(String key: set) {
			//通过键获取值
			String value = map.get(key) ;
			System.out.println(key+"="+value);
		}
//第二种:Set<Map.Entry<K,V>> entrySet() :获取键值对象
将map集合中的映射关系存入到set集合中,这个关系的数据类型为:Map.Entry
Map.Entry接口
  	此接口在java.util包中,其实Entry也是一个接口,它是Map接口中的一个内部接口  ,getKey()和getValue是接口Map.Entry<K,V>中的方法,返回对应的键和对应的值

		//获取键值对对象
		Set<Map.Entry<String, String>> entrySet = map.entrySet() ;
		//遍历所有的键值对
		for(Map.Entry<String, String> entry: entrySet) {
			//K getKey():获取键
		   // V getValue():获取值
			String key = entry.getKey() ;
			String value = entry.getValue() ;
			System.out.println(key+"---"+value);
		}
//Map.Entry的剖析和getKey(),getValue()的由来:
interface Map{
 //此内部接口的特点是静态的,而且是对外提供访问的
     public static interface Entry{

         //因为具体情况要视情况而定,所以是抽象的,具体由子类来实现

         public abstract Object getKey();
         public abstract Object getValue();   
                  }
             }
abstract class HashMap implements Map{
    //内部类实现Map.Entry
    abstract class Hahs implements Map.Entry{
        public Object getKey(){}
        public Object getValue(){}
    }
    

常见问题:

     Entry是接口 ,但是为什么不定义定义在外面呢?

     原因:
      Entry代表的是映射关系,先有Map集合,才有的映射关系,所以它是Map集合内部的事物,因此将Entry定义为
 在Map的内部集合,可以直接访问Map集合中的元素
     在API文档中有 public static interface Map.Entry<K,V>  其中被static静态修饰,只有接口在
 成员位置上才能加静态修饰符 ,说明其是内部接口

keySet()取值方式示例图
在这里插入图片描述
entrySet()取值方式示例图:
在这里插入图片描述

HashMap

HashMap集合:底层基于哈希表,不能保证顺序恒久不变

	//创建一个HashMap集合对象
	HashMap<Integer, String> hm = new HashMap<Integer, String>();
	//添加元素
	hm.put(1, "马云") ;
	hm.put(3, "马化腾") ;
	hm.put(4, "裘波君") ;
	hm.put(6, "雷军")  ;
	hm.put(3, "王健林") ;
	
	//遍历
	Set<Integer> set = hm.keySet() ;
	for(Integer key :set) {
		String value = hm.get(key) ;
		System.out.println(key+"---"+value);
	}
	1---马云
	3---王健林
	4---裘波君
	6---雷军

```java
	//创建HashMap集合对象
		HashMap<String, Student> map = new HashMap<String, Student>() ;
		
		//创建几个学生对象
		  //Student类省略。。。。。注意重写equal、hashcode
		Student s1 = new Student("里皮", 70) ;
		Student s2 = new Student("瓜迪奥拉", 50) ;
		Student s3 = new Student("扎叔", 60) ;
		Student s4 = new Student("穆里尼奥", 65) ;
		Student s5 = new Student("文章", 36) ;
		//添加元素
		map.put("it001", s1);//不能写成map.put(s1),必须是(k,v)格式
		map.put("it002", s2);
		map.put("it003", s3);
		map.put("it004", s4);
		map.put("it002", s5);
	//此处it002会充当key,s5与s2的key相同,s5的内容会覆盖s2的(文章替代瓜迪奥拉)
		
		//遍历
		Set<String> set = map.keySet() ;
		for(String key:set) {
			//通过键获取值
			Student value = map.get(key) ;
			System.out.println(key+"---"+value.getName()+"---"+value.getAge());
		}
		   /*it004---穆里尼奥---65
			it003---扎叔---60
			it002---文章---36
			it001---里皮---70*/
		
HashMap<Student, String> map = new HashMap<Student, String>() ;
			
			//创建几个学生对象
			Student s1 = new Student("里皮", 70) ;
			Student s2 = new Student("瓜迪奥拉", 50) ;
			Student s3 = new Student("扎叔", 60) ;
			Student s4 = new Student("穆里尼奥", 65) ;
			Student s5 = new Student("里皮", 68) ;
			Student s6 = new Student("穆里尼奥", 65) ;
			
			//添加元素
			map.put(s1, "9527") ;
			map.put(s2, "9809") ;
			map.put(s3, "9528") ;
			map.put(s4, "9529") ;
			map.put(s5, "9630") ;
			map.put(s6, "9270") ;
			
			//遍历
			Set<Student> set = map.keySet() ;
			for(Student key :set) {
				String value = map.get(key) ;
				System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
			}
			/*
			瓜迪奥拉---50---9809
			扎叔---60---9528
			穆里尼奥---65---9270
			里皮---68---9630	
			里皮---70---9527
		//整个(里皮,70)充当一个key,与(里皮,70)key不一致,不会替换(里皮,68)
			*/
			

* LinkedHashMap

  • 哈希表和链接列表实现,具有可预知的迭代顺序
  • 哈希表:元素唯一
  • 链表:有序性
import java.util.LinkedHashMap;
import java.util.Properties;
import java.util.Set;


public class LinkedHashMapDemo {

	public static void main(String[] args) {
		
		//创建一个LinkedHashMap集合
		LinkedHashMap<String, String> link = new LinkedHashMap<String, String>() ;
		//添加元素
		link.put("hello", "你好") ;
		link.put("hello", "嘞吼") ;
		link.put("world", "世界") ;
		link.put("java", "爪哇") ;
		link.put("java", "爪哇2") ;
		
		//遍历
		Set<String> set = link.keySet() ;
		for (String key : set) {
			String value = link.get(key) ;
			/*
			 * 	hello----嘞吼
				world----世界
				java----爪哇2
			 * */
			System.out.println(key+"----"+value);
		}
	}
}
hello----嘞吼
world----世界
java----爪哇2


TreeMap

import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapDemo {

	public static void main(String[] args) {
		
		//创建一个TreeMap集合对象
		//TreeMap--->底层红黑树结构  public TreeMap(Comparator<E> comparator)
		TreeMap<Student, String> tm = new TreeMap<Student, String>(new Comparator<Student>() {
 //接口的匿名内部类
			@Override
			public int compare(Student s1, Student s2) {
				//return 0;
				//主要条件,按照年龄从小到大进行排序
				int num = s1.getAge() - s2.getAge() ;
				//年龄一样,不一定是同一个人
				int num2 = (num==0)?(s1.getName().compareTo(s2.getName())):num ;
				return num2 ;
			}
		
		}) ;
		
		
		Student s1 = new Student("潘安", 28) ;
		Student s2 = new Student("柳下惠", 35) ;
		Student s3 = new Student("唐伯虎", 35) ;
		Student s4 = new Student("燕青", 26) ;
		Student s5 = new Student("李白", 38) ;
		Student s6 = new Student("唐伯虎", 35) ;
		
		//添加元素
		tm.put(s1, "元朝") ;
		tm.put(s2, "明朝") ;
		tm.put(s3, "明朝") ;
		tm.put(s4, "宋朝") ;
		tm.put(s5, "唐朝") ;
		tm.put(s6, "宋朝") ;
		
		//遍历
		Set<Student> set = tm.keySet() ;
		for(Student key:set) {
			String value = tm.get(key) ;
			System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
		}
		
	}
}

//Student类
package com.qianfeng.map_05;

public class Student {
	
	private String name ;
	private int age ;
	
	//alt+shift+s--->o
	public Student() {
		super();
	}
	
	
	//alt+shift+s--->c
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}


	//alt+shift+s--->r
	public int getAge() {
		return age;
	}



	public void setAge(int age) {
		this.age = age;
	}



	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	//toString()
	alt+shift+s--->s
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}
输出结果:
燕青---26---宋朝
潘安---28---元朝
唐伯虎---35---宋朝
柳下惠---35---明朝
李白---38---唐朝

HashMap与TreeMap区别:


(1)HashMap(): 构建一个空的哈希映像
(2)HashMap(Map m): 构建一个哈希映像,并且添加映像m的所有映射
(3)HashMap(int initialCapacity): 构建一个拥有特定容量的空的哈希映像
(4)HashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的哈希映像

TreeMap:基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。

(1)TreeMap():构建一个空的映像树
(2)TreeMap(Map m): 构建一个映像树,并且添加映像m中所有元素
(3)TreeMap(Comparator c): 构建一个映像树,并且使用特定的比较器对关键字进行排序
(4)TreeMap(SortedMap s): 构建一个映像树,添加映像树s中所有映射,并且使用与有序映像s相同的比较器排序

两种常规Map性能
HashMap:适用于在Map中插入、删除和定位元素。
Treemap:适用于按自然顺序或自定义顺序遍历键(key)。

HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。
HashMap 非线程安全 TreeMap 非线程安全

HashMap和Hashtable的区别?

  • HashMap:底层是哈希表结构,保证元素唯一,不能保证顺序恒久不变

  • 它存储null键 null值----->线程不安全,不同步—执行效率高

  • Hashtable<K,V>:不允许null键和null值出现 底层哈希表实现

  • 线程安全,同步----->执行效率低

  • Hashtable存在子类:Properties 属性集合类 唯一特点:键和值都是String

  • 线程安全的类:

  •  	StringBuffer,Vector,Hashtable
    
  • List,Set,Map等接口是否都继承子Map接口

	Collection集合单列集合的根接口			
   			List和Set属于Collection子接口		
    Map 存储键值元素的根接口
  			 HashMap,TreeMap				
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值