黑马程序员---Java基础---Map集合

本文深入讲解Java中的Map集合,包括其基本概念、常用方法、遍历方式及不同实现类的特点。并通过实例演示如何使用Map集合解决实际问题。

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


一.Map集合

         1.什么是Map集合

                   Map集合用来存储键值对, 每次存储2个对象, 一个键一个值, 可以根据键查找值, 键必须唯一.

         2.Map集合常用方法

                   Vput(K key, V value)

                            存储一个键值对, 如果键在集合中存在, 值将会覆盖原有值, 并且返回原有值.

                   Vget(Object key)

                            根据键获取值, 如果不存在, 返回null

                   Vremove(Object key)

                            根据键删除值, 并将值返回, 如果不存在, 返回null

                   booleancontainsKey(Object key)

                            判断指定的键对象是否存在

package cn.itcast.day18.map;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MapDemo {

	public static void main(String[] args) {
//		demo1();
//		demo2();
//		demo3();
//		demo4();
//		demo5();
//		demo6();
//		demo7();
//		demo8();
	}

	private static void demo8() {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("张三", 80);		
		map.put("李四", 85);
		map.put("王五", 80);
		map.put("赵六", 90);
		Collection<Integer> c = map.values();		// 获取Map中所有值组成的集合
		for (Integer i : c) 
			System.out.println(i);			// 打印每一个值
	}

	private static void demo7() {
		Map<String, Integer> map1 = new HashMap<String, Integer>();
		System.out.println(map1.put("张三", 81));	// 如果键不存在, 存储之后返回null
		System.out.println(map1.put("李四", 82));
		System.out.println(map1.put("王五", 83));
		System.out.println(map1.put("张三", 90));	// 如果键存在, 将原有的值返回
	}

	private static void demo6() {
		Map<String, Integer> map1 = new HashMap<String, Integer>();
		map1.put("张三", 81);		
		map1.put("李四", 82);
		map1.put("王五", 83);
		
		System.out.println(map1);
		System.out.println(map1.remove("张三"));		// 删除键为张三的记录, 并且返回张三的值, 81
		System.out.println(map1.remove("赵六"));		// 删除键为赵六的记录, 不存在, 返回null
		System.out.println(map1);
	}

	private static void demo5() {
		Map<String, Integer> map1 = new HashMap<String, Integer>();
		map1.put("张三", 81);		
		map1.put("李四", 82);
		map1.put("王五", 83);
		
		Map<String, Integer> map2 = new HashMap<String, Integer>();
		map2.put("李四", 91);
		map2.put("王五", 92);
		map2.put("赵六", 93);
		
		map1.putAll(map2);		// 把map2中的所有元素装入map1
		
		System.out.println(map1);
	}

	private static void demo4() {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("张三", 80);		
		map.put("李四", 85);
		map.put("王五", 80);
		map.put("赵六", 90);
		System.out.println(map.containsValue(80));
		System.out.println(map.containsValue(81));
		System.out.println(map.containsValue(82));
		System.out.println(map.containsValue(83));
		System.out.println(map.containsValue(84));
		System.out.println(map.containsValue(85));
	}

	private static void demo3() {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("张三", 80);		
		map.put("李四", 85);
		map.put("王五", 80);
		map.put("赵六", 90);
		
		System.out.println(map.containsKey("张三"));
		System.out.println(map.containsKey("李四"));
		System.out.println(map.containsKey("王五"));
		System.out.println(map.containsKey("赵六"));
		System.out.println(map.containsKey("王二麻子"));
	}

	private static void demo2() {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("张三", 80);		
		map.put("李四", 85);
		map.put("王五", 80);
		map.put("赵六", 90);
		
		System.out.println(map);
		map.clear();
		System.out.println(map.isEmpty());
		System.out.println(map.size());
		System.out.println(map);
	}

	private static void demo1() {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("张三", 80);		// 存储键值对
		map.put("李四", 85);
		map.put("王五", 80);
		map.put("赵六", 90);
		map.put("赵六", 95);		// 如果键重复, 后来的值覆盖原有值

		System.out.println(map.get("张三"));		// 根据键获取值
		System.out.println(map.get("李四"));
		System.out.println(map.get("王五"));
		System.out.println(map.get("赵六"));
		
		System.out.println(map);	// 打印map的toString(), 内部会将所有的键和值连接在一起
	}

}

         3.Map集合的遍历

                   keySet:

                            Map集合的keySet()方法可以得到一个所有键对象组成的Set集合

                            遍历这个Set集合可以得到每一个键对象

                            再根据键对象即可获取值

                   entrySet:

                            Map集合的entrySet()方法可以得到一个所有Entry对象(键值对)组成的Set集合

                            遍历这个Set集合可以得到每一个Entry对象

                            再使用Entry的getKey()方法和getValue()方法获取键和值

package cn.itcast.day18.map;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class MapIterateDemo {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("张三", 80);		
		map.put("李四", 85);
		map.put("王五", 80);
		map.put("赵六", 90);
		
//		iterate1(map);
//		iterate2(map);
	}

	private static void iterate2(Map<String, Integer> map) {
		Set<Entry<String, Integer>> set = map.entrySet();		// Map集合的entrySet()方法可以得到一个所有Entry对象(键值对)组成的Set集合
		for (Entry<String, Integer> e : set)				// 遍历这个Set集合可以得到每一个Entry对象
			System.out.println(e.getKey() + ": " + e.getValue());	// 再使用Entry的getKey()方法和getValue()方法获取键和值
	}

	private static void iterate1(Map<String, Integer> map) {
		Set<String> set = map.keySet();					// Map集合的keySet()方法可以得到一个所有键对象组成的Set集合
		for (String key : set)					<span style="white-space:pre">	</span>// 遍历这个Set集合可以得到每一个键对象
			System.out.println(key + ": " + map.get(key));		// 根据键对象即可获取值
	}

}

         4.Map集合的常用实现类

                   HashMap:                  使用哈希算法对键对象去重复

* HashMap存储一个键值对的时候, 先会调用键对象的hashCode()方法得到哈希值

* 然后在集合中查找是否有哈希值相同的键对象

*             如果没有哈希值相同的键对象,直接将键值对存入

  *             如果有哈希值相同的键对象,逐个和这些键对象进行equals()方法比较

  *                      比较的结果为false就将键值对存入

  *                      比较的结果为true则用新的值覆盖原有值

* HashMap在根据指定的键对象获取值的时候, 先对键对象调用hashCode()方法, 得到哈希值

  * 然后在集合中查找哈希值相同的对象, 逐个equals()方法比较

  * 找到equals()结果为true的键值对, 将值返回


                   TreeMap:                   使用二叉树算法对键对象排序

* TreeMap在存储键值对的时候, 会调用键对象的compareTo()方法和集合中其他的键对象进行比较, 根据比较结果以二叉树形式存储

  * 如果TreeMap创建的时候在构造函数中传入了比较器, 那么存储顺序以比较器为准

                   LinkedHashMap:      HashMap的子类, 去重复的同时保留存储顺序

                   Hashtable:                 和HashMap原理相同, 都是使用哈希算法去重复. 线程安全, 效率略低. 键和值都不允许为null

                   Properties:                键和值都是String, 用来存储一些配置项

二.练习

  1.定义一个函数, 函数中接收一个String, 统计每个字符出现的次数

package cn.itcast.day19.review;

import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;

/*
 * 定义一个函数, 函数中接收一个String, 统计每个字符出现的次数
 */
public class Exercise5 {

	public static void main(String[] args) {
		countTimes1("bbcddddaaa");	// {b=2, c=1, d=4, a=3}<span style="white-space:pre">	</span>	
		countTimes2("bbcddddaaa");	// {c=1, b=2, a=3, d=4}
	}
	

	public static void countTimes1(String s) {
		Map<Character, Integer> map = new LinkedHashMap<Character, Integer>();	// 创建一个Map<Character, Integer>, 用来存储字符和次数
		char[] arr = s.toCharArray();			<span style="white-space:pre">	</span>// 将字符串转为字符数组
		for (char c : arr) {					// 循环遍历每个字符
			if (map.containsKey(c))	{			// 判断Map中是否包含这个字符
				map.put(c, map.get(c) + 1);		// 如果包含, 将以前的次数获取出来, 加1, 再覆盖
			} else { 
				map.put(c, 1);				// 如果不包含, 将字符存入, 次数存1
			}
		}
		System.out.println(map);				// 打印Map中存的结果
	}
	
	private static void countTimes2(String s) {
		Map<Character, Integer> map = new HashMap<Character, Integer>();
		for (char c : s.toCharArray()) 
			map.put(c, map.containsKey(c) ? map.get(c) + 1 : 1);
		
		// 以上的操作统计出了每个字符出现的次数, 但是没有顺序, 只要将这些结果排序即可
		
		Set<Entry<Character, Integer>> entrySet = map.entrySet();		<span style="white-space:pre">				</span>// 获取出map集合中的所有Entry
		TreeSet<Entry<Character, Integer>> treeSet = new TreeSet<Entry<Character,Integer>>(new EntryComparator());	// 创建TreeSet用来排序
		treeSet.addAll(entrySet);		// 将entrySet中的键值对都装入treeSet, 排序
		System.out.println(treeSet);	<span style="white-space:pre">	</span>// 打印结果
	}
}

class EntryComparator implements Comparator<Entry<Character, Integer>> {
	public int compare(Entry<Character, Integer> o1, Entry<Character, Integer> o2) {
		int gap = o1.getValue() - o2.getValue();			// 值的比较结果
		return gap != 0 ? gap : o1.getKey() - o2.getKey();		// 如果值不一样, 按照值排序, 值一样的话按照键排序
	}
}
2.从键盘接收3个学生的考试成绩, 对其按照总分排序, 输出到屏幕

package cn.itcast.day18.exercise;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.TreeSet;


/*
	从键盘接收3个学生的考试成绩, 对其按照总分排序, 输出到屏幕. 
		考试成绩输入格式:
			张三,80,85,80
			李四,70,70,80
			王五,90,90,90
		屏幕输出格式:
			王五,90,90,90,270	
			张三,80,85,80,245
			李四,70,70,80,220
*/
public class Exercise4 {

	public static void main(String[] args) throws Exception {
		System.out.println("请输入学生成绩:");
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		TreeSet<Student> ts = new TreeSet<Student>();	<span style="white-space:pre">		</span>// 定义TreeSet<Student>, 用来对学生排序
		for (;;) {							// 定义循环
			String line = br.readLine();				// 读取一行
			if (line.equals("quit"))			<span style="white-space:pre">	</span>// 如果读到"quit", 退出输入
				break;
			String[] arr = line.split(",");				// 按逗号分割成String[]
			Student stu = new Student(arr[0], Integer.parseInt(arr[1]), Integer.parseInt(arr[2]),Integer.parseInt(arr[3]));		
			ts.add(stu);						// 装入TreeSet
		}
		System.out.println("考试成绩排序后的结果:");
		for (Student stu : ts)						// 遍历TreeSet
			System.out.println(stu);				// 打印Student
	}

}

class Student implements Comparable<Student> {
	private String name;
	private int chinese;
	private int math;
	private int english;
	private int sum;
	
	public Student(String name, int chinese, int math, int english) {
		this.name = name;
		this.chinese = chinese;
		this.math = math;
		this.english = english;
		this.sum = chinese + math + english;
	}

	public String toString() {
		return name + "," + chinese + "," + math + "," + english + "," + sum;
	}

	public int compareTo(Student o) {
		int i = o.sum - this.sum;
		return i != 0 ? i : 1;
	}
}

三.集合总结

Conllection :单列集合,一次存一个对象

                  List:可重复,有索引

ArrayList: 数组实现,查找快,增删慢

LinkedList:链表实现,增删快,查找慢

boolean add(Object obj)

向集合中添加一个对象, 如果改变了集合的结构, 返回true. 集合可以添加任意类型的对象.

Object remove(int index)

删除指定索引上的元素, 并且返回这个元素

Object  set(int index, Object obj)

将集合中指定位置的元素替换为指定对象

Object get(int index)

从集合中获取指定索引上的对象.

遍历:

1,增强for循环

for(类型 变量名 : 容器) { 循环体 }, 容器长度是多少循环体就执行多少次, 变量每次引用容器中的一个元素

2,迭代器

使用iterator()方法获取一个迭代器(Iterator对象), 调用hasNext()方法判断是否包含下一个元素,调用next()方法获取元素.

3,for循环

循环size()次,每次调用一个get()方法 

Vector:原理和ArrayList相同,线程安全,效率较慢

Stack: 栈,先进后出

push():压入对象

pop():从最后一个开始拿出对象

                           

                  Set:无重复,无索引

HashSet: 使用哈希算法,去重复,速度快,无顺序

add():向集合中添加一个对象, 如果改变了集合的结构, 返回true. 集合可以添加任意类型的对象.

remove();

size();

LinkedHashSet: 使用哈希算法,但是可以保留存储顺序

TreeSet: 使用二叉树算法,按照制定顺序排序:自然排序、比较器

TreeSet的add方法会将对象转为Comparable,然后调用compareTo方法, 所以存储在TreeSet中的对象必须实现Comparable, 重写compareTo方法

遍历:1,迭代器

2,增强for循环

 

 Map:一个键值对的集合,键唯一,可根据键查找值

HashMap: 使用哈希算法去重复,无顺序

put(key,value):增加键值关联(增加对象)

get(key):通过键,查找值

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

keySet(): 返回此映射中所包含的键的Set 视图。

remove():删除

size():长度

LinkedHashMap:HashMap的子类,去重复的同时,按照存储顺序排列

Hashtable:和HashMap同原理,线程安全,效率偏低,键和值都不能为null

Properties:键值都是Stirng类型,用来存储一些配置项

TreeMap:使用二叉树算法对键值对排序


------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值