目录

一、Map的含义

二、Map的特点

三、Map结构图

四、Map常用方法

五、HashMap

(1)使用HashMap演示以上方法

(2)Map遍历

(3)案例

六、HashTable

七、TreeMap

八、LinkedHashMap

九、斗地主练习


一、Map的含义

Map:双列集合的顶层接口

Map:单词含义,地图,地图上的每个点,都表示了生活中的一个具体位置。地图的点和生活中的位置,有一个一一对应的关系,这种关系是通过穷举的方式来描述的。

Map是一个以键(key)值(value)对形式存储数据的容器。

二、Map的特点

Map 是一个接口,但不是Collection的子接口。

Map以键值对的形式存储数据,每个键(key)对应一个值(value)。

Map 中的键不能重复(唯一)

Map 中的值可以重复。

主要实现类 HashMap Hashtable TreeMap ...

三、Map结构图

Java 映射表 java map映射_java

四、Map常用方法

put(K key, V value)  向Map中添加数据

putAll(Map<? extends K,? extends V> m) 向Map中添加另一个Map集合。

isEmpty()  Map中是否包含数据

size() Map中包含键值对的个数

get(key) 根据key获取value

clear() 清空Map

containsKey(key) 判断Map中是否包含key

containsValue(value) 判断Map中是否包含value

keySet() 返回Map中所有key 组成的Set集合

values() 返回Map中所有value组成的集合 (返回值Collection类型)

entrySet() 返回此映射中包含的映射关系的 Set 视图

五、HashMap

HashMap是Map接口的最常用实现类,底层是哈希表形式存储的,非线程安全的,允许有null键值对。

(1)使用HashMap演示以上方法

public static void main(String[] args) {
		
		Map<String,String> map = new HashMap<String,String>();  
		map.put("aaa","111");    // key不能重复,value 可以重复
		map.put("bbb","222");
		map.put("ccc", "333");
		map.put("ddd", "111");  // value可以重复
		map.put(null,null);
		System.out.println(map.put("aaa", "100"));  // key不能重复,会覆盖原有的value
		// put方法的返回值  是存入这个key时,之前这个key值在map中对应的value值
		System.out.println(map.size());  // 获得Map中包含多少元素
		String str = map.get("aaa");     // 根据key获取value
		System.out.println(str);
		
		String str2 = map.get("xxx");  // 当key不存在时返回null
		System.out.println(str2);
		
		System.out.println(map.containsKey("aaa"));    // 判断是否包含某个key
		System.out.println(map.containsKey("xxx"));
		System.out.println(map.containsValue("222"));   //判断是否包含某个value
		System.out.println(map.containsValue("555"));
		
		map.remove("aaa");  // 根据key删除数据
		System.out.println(map.get("aaa"));
		
		System.out.println(map.isEmpty());   //判断map中是否包含数据
		
		map.clear();  // 清空map
		System.out.println(map.isEmpty());  
}

(2)Map遍历

方式一:使用keySet()方法

1、获取Map集合中的所有键,放到一个Set集合中,遍历该Set集合,获取到每一个键,根据键再来获取对应的值。【根据键获取值】

2、获取Map集合中的所有键

            Set<K>   keySet()

Java 映射表 java map映射_Java 映射表_02

Set<String> keys = map.keySet();
		
for(String key:keys){
	System.out.println(key+"--->"+map.get(key));
}

方式二:使用entrySet()方法

获取Map集合中的所有键值对对象(Entry),到Set集合中,遍历Set集合,拿到的是每个键值对对象(Entry),从这个对象中分别获取键和值。【根据键值对对象获取键和值】

根据Map集合获取所有的键值对对象,到一个Set集合中

           Set<Map.Entry<K, V>>  entrySet()

Entry是Map接口中的内部接口,访问的方式:Map.Entry

Entry的常用方法:

   getKey()获取当前键值对对象的键

   getValue()获取当前键值对对象的值

Java 映射表 java map映射_java_03

Set<Map.Entry<String,String>> es = map.entrySet();
for(Map.Entry<String,String> entry:es){
	//System.out.println(entry);
	System.out.println(entry.getKey()+"--->"+entry.getValue());
}

(3)案例

案例1:编写一个方法,完成英译汉翻译功能。

      dog--->狗

      cat--->猫

      pig--->猪

      monkey--->猴

      cow---> 牛

public class Demo03_Map练习_英译汉 {
	public static void main(String[] args) {
		String result = translate("lion");
		if(result!=null){
			System.out.println(result);
		}else{
			System.out.println("查无此词");
		}
	}

	public static String translate(String word){
		// 词典
		Map<String,String> map = new HashMap<String, String>();
		
		map.put("cat", "猫");
		map.put("dog", "狗");
		map.put("monkey", "猴子");
		map.put("pig", "猪");
		map.put("elephant", "大象");
		map.put("tiger", "老虎");
		map.put("fox", "狐狸");
		map.put("lion", "狮子");
		
		String result = map.get(word);
		return result;
	}
}

案例2:键盘录入一个字符串,统计每个字符出现的次数

例如,录入aaaabbccddd!@#@#$@#$%cc66ff

打印出来:a有4个,b有2个,c有4个,d有3个,!有1个,@有3个,$有2个,%有1个,6有2个,f有2个

public class Demo04_Map练习_统计字符出现的次数 {

	/*
键盘录入一个字符串,统计每个字符出现的次数
例如,录入aaaabbccddd!@#@#$@#$%cc66ff
打印出来:a有4个,b有2个,c有4个,d有3个,!有1个,@有3个,$有2个,%有1个,6有2个,f有2个
	 
	思路:
	    1 使用Map   key-->字符   value-->次数
	    2 遍历字符串取到字符
	    3 判断取到的字符在map的key中是否存在   存在,根据key取出次数 再+1 存回去。 不存在,把取到字符当成key存入map并存入次数(value) 1
	 * */
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String str = sc.nextLine();
		Map<String,Integer> map = new HashMap<String, Integer>();
		for(int i=0;i<str.length();i++){
			char c = str.charAt(i);
			String key = c+"";
//Integer count = map.get(c+"");  // 为null 说明map中没有这个字符
			boolean flag = map.containsKey(key);
			
			int count = 0;
			if(flag){
				count = map.get(key);
			}
			map.put(key, ++count);
		}
		
		Set<Map.Entry<String,Integer>> set = map.entrySet();
		
		for(Map.Entry<String,Integer> entry:set){
			System.out.println(entry.getKey()+"  :  "+entry.getValue());
		}	
	}
}

六、HashTable

Hashtable是一个比较古老的类(从JDK1.2开始),特点是线程安全的,不允许有null键值对。用法和HashMap相同,基本被HashMap替代。

1、面试常见问题HashMap和Hashtable的区别?

HashMap: 线程不安全,允许null键值对

Hashtable: 线程安全,不允许null键值对

七、TreeMap

特点:会根据key值进行升序排列。

public class Demo06_TreeMap {
	/*
	 * 底层是由红黑数(自平衡的二叉树)来实现的  会根据key升序排序
	 * key需要有排序的能力 或传入比较器
	 * */
	public static void main(String[] args) {
		Map<String,String> map = new TreeMap<String,String>();
		map.put("bbb","222");
		map.put("ddd","444");
		map.put("eee","555");
		map.put("ccc","333");
		map.put("aaa","111");
		
		Set<Map.Entry<String,String>> set = map.entrySet();
		
		for(Map.Entry<String,String> entry:set){
			System.out.println(entry.getKey()+"---"+entry.getValue());
		}
	}
}

八、LinkedHashMap

是HashMap的一个子类

和HashMap的不同之处在于,具有可预知的迭代顺序,存储键值对的顺序和遍历集合时取出键值对的顺序一致。

public class Demo07_LinkedHashMap {
	public static void main(String[] args) {
/*
LinkedHashMap 是 HashMap的子类   不同在于 LinkedHashMap有序(和添加顺序一致)
 */
		Map<String,String> map = new LinkedHashMap<String,String>();
		map.put("aaa","111");
		map.put("bbb","222");
		map.put("ccc","333");
		map.put("ddd","444");
		
		Set<Map.Entry<String,String>> set = map.entrySet();
		
		for(Map.Entry<String,String> entry:set){
			System.out.println(entry.getKey()+"   "+entry.getValue());
		}
	}
}

九、斗地主练习

斗地主的制牌、洗牌和发牌

思路

  1、制牌:1~K一共13个数字,四个花色,4 * 13张牌,小王、大王

  2、洗牌:shuffle将集合中的字符串随机置换

  3、发牌:将一个集合中的元素,分发到3个集合中

 

问题

  发牌之后,每个人的牌都没有顺序,无法洗牌,字符串的字典顺序,和扑克牌中的大小顺序不同,不能使用字典顺序来直接排序

 

解决

  1、通过穷举,手动将所有牌面的大小,全都定义出来,每个牌面上的字符串,都可以对应一个其在扑克牌中的大小的数字(字符串和数字的对应关系)

  2、可以给牌面的大小排序,对应到某个牌面

Java 映射表 java map映射_Java 映射表_04

发牌后不带自动排序的实现

public class Demo02_斗地主_制牌_洗牌_发牌 {
	public static void main(String[] args) {
		String[] nums = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
		String[] colors = {"红桃","黑桃","梅花","方块"};
		List<String> poker = new ArrayList()<String>();
		//制牌
		for(String color:colors){
			for(String num:nums){
				poker.add(color+num);
			}
		}
		poker.add("小王");
		poker.add("大王");
		
		//洗牌
		Collections.shuffle(poker);
		
		//发牌
		List<String> xiaodao = new ArrayList<String>();
		List<String> longwu = new ArrayList<String>();
		List<String> me = new ArrayList<String>();
		List<String> dipai = new ArrayList<String>();
		
		for(int i=1;i<=3;i++){
			dipai.add(poker.remove(0));
		}
		while(true){
			if(!poker.isEmpty()){
				xiaodao.add(poker.remove(0));
			}
            if(!poker.isEmpty()){
				longwu.add(poker.remove(0));
			}
            if(!poker.isEmpty()){
				me.add(poker.remove(0));
			}else{
				break;
			}
		}
		System.out.println(dipai);
		System.out.println(xiaodao);
		System.out.println(longwu);
		System.out.println(me);
	}
}

发牌后带自动排序的实现

public class Demo03_斗地主_制牌_洗牌_发牌_有序 {

	public static void main(String[] args) {

		String[] nums = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2" };
		String[] colors = { "红桃", "黑桃", "梅花", "方块" };
		// 要制作一个表格,表格中存放的是 序号和牌的对应
		Map<Integer, String> table = new HashMap<Integer, String>();
		// Poker中只存序号就可以了,以后要用牌的时候,就到table中根据序号取到对应的牌即可
		List<Integer> poker = new ArrayList<Integer>();

		int count = 0;

		for (String num : nums) {

			for (String color : colors) {

				table.put(count, color + num); // 把序号和生成的牌装入table表格中
				poker.add(count);

				count++;

			}
		}

		table.put(count, "小王");
		poker.add(count);

		count++;
		table.put(count, "大王");
		poker.add(count);
		// 洗牌
		Collections.shuffle(poker);
		// 发牌
		List<Integer> dipai = new ArrayList<Integer>();
		List<Integer> xiaodao = new ArrayList<Integer>();
		List<Integer> longwu = new ArrayList<Integer>();
		List<Integer> me = new ArrayList<Integer>();

		for (int i = 1; i <= 3; i++) {
			dipai.add(poker.remove(0));
		}

		while (true) {

			if (!poker.isEmpty()) {
				xiaodao.add(poker.remove(0));
			}

			if (!poker.isEmpty()) {
				longwu.add(poker.remove(0));
			}

			if (!poker.isEmpty()) {
				me.add(poker.remove(0));
			}else{
				
				break;
			}
		}
		Collections.sort(xiaodao);
		Collections.sort(longwu);
		Collections.sort(me);
	
		System.out.println(kanpai(dipai,table));
		System.out.println(kanpai(xiaodao,table));
		System.out.println(kanpai(longwu,table));
		System.out.println(kanpai(me,table));
	}
	
	public static String kanpai(List<Integer> list,Map<Integer,String> map){
		StringBuilder sb = new StringBuilder("[");
		
		for(Integer x:list){
			sb.append(map.get(x)).append(",");
		}
		return sb.replace(sb.length()-1,sb.length(),"]").toString();
	}
}