Java集合框架(三)---Map

接口Map<K,V>
Map集合:该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
1,添加
put(K key, V value)
putAll(Map<? extends K, ? extends V> m)
2,删除
clear()
remove(Object key)
3,判断
containsValue(Object value)
containsKey(Object key)
isEmpty()
4,获取
get(Object key)
size()
values()
entrySet()
keySet()
Map
—Hashtable:底层是哈希数据结构,不可以存入null键null值,该集合是线程同步的。jdk1.0,效率低
—HashMap:底层是哈希表数据结构,允许使用null值和null键,该集合是不同步,jdk1.2效率高
—TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map结合中的键排序

和Set很像,其实Set底层就是使用了Map集合。

Map共性方法

public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
		
		 Map<String, String> map = new HashMap<String, String>();
		 //添加元素,如果出现添加时相同的键,那么后添加的值会覆盖原有键值对,并put方法会返回覆盖的值
		 map.put("01", "zhangsan1"); 
		 map.put("02", "zhangsan2");
		 map.put("03", null);
		 map.put("04", "zhangsan4");
		 
		 sop("containsKey = "+map.containsKey("01"));
		 sop("remove =  "+map.remove("02"));
		 //可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断
		 sop("get = "+map.get("03"));
		 //获取map集合中所用的集合,是无序的
		 Collection<String> collection = map.values();
		sop(collection); 	
	}

打印结果:

containsKey = true
remove =  zhangsan2
get = null
[zhangsan4, zhangsan1, null]

Map-keySet

Set keySet:将Map中所有的键存入到Set集合,因为Set具备迭代器。所以可以迭代方式取出所有的键,在根据get方法,获取每一个键对应的值。

Map 集合的取出原理:将map集合转成Set集合,在通过迭代器取出。

public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
		 Map<String, String> map = new HashMap<String, String>();
		 map.put("01", "zhangsan1");
		 map.put("02", "zhangsan2");
		 map.put("03", "zhangsan3");
		 map.put("04", "zhangsan4");
		 //先获取Map集合的所有键的Set集合,keySet()
		 Set<String> keyset = map.keySet();
		 //有了Set集合,就可以获取其迭代器
		 Iterator<String> iterator = keyset.iterator();
		 while (iterator.hasNext()) {
			String string = (String) iterator.next();
			sop("key = "+string+", value = "+ map.get(string));
		}
	}

打印结果:

key = 04, value = zhangsan4
key = 01, value = zhangsan1
key = 02, value = zhangsan2
key = 03, value = zhangsan3

keyset原理图:
在这里插入图片描述
Map-entrySet

Set<Map.Entry<k,v> entrySet: 将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是Map.Entry

public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
		
		 Map<String, String> map = new HashMap<String, String>();
		 map.put("01", "zhangsan1");
		 map.put("02", "zhangsan2");
		 map.put("03", "zhangsan3");
		 map.put("04", "zhangsan4");
		 
		 Set<Map.Entry<String, String>> entries=  map.entrySet();
		 Iterator<Map.Entry<String, String>> iterator = entries.iterator();
		 while (iterator.hasNext()) {
			 Map.Entry<String, String> mEntry = iterator.next();
				String key = mEntry.getKey();
				String value = mEntry.getValue();
			 sop("key = "+key+", value = "+ value);
 		 }
	}

打印结果:

key = 04, value = zhangsan4
key = 01, value = zhangsan1
key = 02, value = zhangsan2
key = 03, value = zhangsan3

entrySet图例
在这里插入图片描述
Map.Entry 其实Entry也是一个接口,它是Map接口中的一个内部接口
在这里插入图片描述
Map练习
每一个学生都有对应的归属地,学生Student,地址String。
学生属性:姓名,年龄
注意:姓名和年龄相同的视为同一个学生,保证学生的唯一性。

1,描述学生
2,定义一个map容器,将学生作为键,地址作为值 存入
3,获取map集合的元素。

class Student implements Comparable<Student>{
	private String name;
	private int age;
	
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 * 一想到Hash集合就要想到HashCode和equals
	 */
	@Override
	public int hashCode() {
		return name.hashCode()+age*34;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
	
		if (!(obj instanceof Student)) {
			throw new ClassCastException("类型不匹配");
		}
		Student other = (Student) obj;
		
		return this.name.equals(other.name) && this.age == other.age;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	//数据有可能会存到二叉树中,所以还是要覆写上排序的方法
	@Override
	public int compareTo(Student o) {
		int num = new Integer(this.age).compareTo(new Integer(o.age));
		if (num == 0) {
			return this.name.compareTo(o.name);
		}
		return num;
	}
}

public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
		
		 HashMap<Student, String> map = new HashMap<Student, String>();
		 
		 map.put(new Student("zhangsan", 18), "beijing");
		 map.put(new Student("lisi", 33), "xian");
		 map.put(new Student("wangwu", 25), "shenzhen");
		 map.put(new Student("xiaoming", 23), "hebei");
		 map.put(new Student("xiaoming", 23), "shanghai");//会覆盖上面的值

		 //第一中方式取出
		 Set<Student> set = map.keySet();
		 Iterator<Student> iterator = set.iterator();
		 while (iterator.hasNext()) {
			Student student = iterator.next();
			String value = map.get(student);
			sop("student:"+student + " , value:"+ value);
		}
		 
		 //第二种取出方式
		 Set<Map.Entry<Student, String>> entries=  map.entrySet();
		 Iterator<Map.Entry<Student, String>> iterator1 = entries.iterator();
		 while (iterator1.hasNext()) {
			 Map.Entry<Student, String> mEntry = iterator1.next();
			 Student key = mEntry.getKey();
	 			String value = mEntry.getValue();
			 sop("key = "+key.toString()+", value = "+ value);
		 }
	}

打印结果:

student:Student [name=wangwu, age=25] , value:shenzhen
student:Student [name=zhangsan, age=18] , value:beijing
student:Student [name=xiaoming, age=23] , value:shanghai
student:Student [name=lisi, age=33] , value:xian
key = Student [name=wangwu, age=25], value = shenzhen
key = Student [name=zhangsan, age=18], value = beijing
key = Student [name=xiaoming, age=23], value = shanghai
key = Student [name=lisi, age=33], value = xian

TreeMap练习
需求:按照学生的姓名进行排序。
因为数据是以键值对形式存在的,所以要使用可以排序的map集合,TreeMap.

class Student implements Comparable<Student>{
	private String name;
	private int age;
	
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 * 一想到Hash集合就要想到HashCode和equals
	 */
	@Override
	public int hashCode() {
		return name.hashCode()+age*34;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
	
		if (!(obj instanceof Student)) {
			throw new ClassCastException("类型不匹配");
		}
		Student other = (Student) obj;
		
		return this.name.equals(other.name) && this.age == other.age;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	//数据有可能会存到二叉树中,所以还是要覆写上排序的方法
	//按照年龄排序
	@Override
	public int compareTo(Student o) {
		int num = new Integer(this.age).compareTo(new Integer(o.age));
		if (num == 0) {
			return this.name.compareTo(o.name);
		}
		return num;
	}
}
class StuComparator implements Comparator<Student>{

	@Override
	public int compare(Student o1, Student o2) {
	//按照年龄排序
		int num = o1.getName().compareTo(o2.getName());
		if (num == 0) {
			return new Integer(o1.getAge()).compareTo(o2.getAge());
		}
		return num;
	}
}

public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
		
		TreeMap<Student, String>  treeMap = new TreeMap<Student, String>(new StuComparator());
		
		treeMap.put(new Student("zhangsan", 18), "beijing");
		treeMap.put(new Student("lisi", 33), "xian");
		treeMap.put(new Student("wangwu", 25), "shenzhen");
		treeMap.put(new Student("xiaoming", 23), "hebei");
		treeMap.put(new Student("xiaoming", 23), "shanghai");

		 Set<Map.Entry<Student, String>> entries=  treeMap.entrySet();
		 Iterator<Map.Entry<Student, String>> iterator1 = entries.iterator();
		 while (iterator1.hasNext()) {
			 Map.Entry<Student, String> mEntry = iterator1.next();
			 Student key = mEntry.getKey();
	 			String value = mEntry.getValue();
			 sop("key = "+key.toString()+", value = "+ value);
		 }
	}

打印结果:

key = Student [name=lisi, age=33], value = xian
key = Student [name=wangwu, age=25], value = shenzhen
key = Student [name=xiaoming, age=23], value = shanghai
key = Student [name=zhangsan, age=18], value = beijing

TreeMap练习2
"shnsjljsjkdjndhskdn"获取该字符串中字母出现的次数。
希望打印结果:a(1)c(2)…

思路:
1,将字符串转换成字符数组,因为要对每一个字母进行操作
2,定义一个Map集合,因为打印结果的字母有顺序,所以使用treemap集合
3,遍历字符数组。将每一个字母作为键去查Map集合,如果返回为null,将将该字母和1存入到Map集合中,如果返回不是null,说明该字母在Map集合已经存在并有对应次数,那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到Map集合中,覆盖原来键对应的值
4,将Map集合中的数据变成指定的字符串形式返回。
在这里插入图片描述

public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
		
		String str = "sh+nsjlj1sjkdjn-dhskdn";
		int count = 0;
		char [] cs = str.toCharArray();
			
		TreeMap<Character,Integer>  treeMap = new TreeMap<Character,Integer>();
		
		for (int i = 0; i < cs.length; i++) {
			
			//如果非字母,继续循环
			if(!(cs[i] >= 'a' && cs[i] <= 'z' || cs[i] >= 'A' && cs[i] <= 'Z'))
			continue;
				
			Integer value = treeMap.get(cs[i]);
			if(value != null)
				count = value;
			count++;
			treeMap.put(cs[i], count);
			
			count =0;
			
			/*或者这样判断,也可以的
			 * if (value == null) {
				treeMap.put(cs[i], 1);
			}else {
				treeMap.put(cs[i], value+1);
			}*/
		}
		
		StringBuffer buffer = new StringBuffer();
		Set<Map.Entry<Character,Integer>> set = treeMap.entrySet();
		Iterator<Map.Entry<Character,Integer>> iterator = set.iterator();
		while (iterator.hasNext()) {
			Map.Entry<Character,Integer> entry = iterator.next();
			buffer.append(entry.getKey() + "("+entry.getValue()+")");
			sop(buffer.toString());
		}
	}

打印结果:

d(3)h(2)j(4)k(2)l(1)n(3)s(4)

Map扩展

map集合被使用是因为具备映射关系,一对多映射
一个学校有多个教室,一个教室里有多个学生

class Student{
	private String id;
	private String name;
	public Student(String id, String name) {
		this.id = id;
		this.name = name;
	}
	public String getId() {
		return id;
	}
	public String getName() {
		return name;
	}
}
public class Demo {
	public static void sop(Object object){
		System.out.println(object);
	}
	public static void main(String[] args) {
		
		HashMap<String, List<Student>> school = new HashMap<String, List<Student>>();
		
		List<Student> aClass = new ArrayList<Student>();
		List<Student> bClass = new ArrayList<Student>();
	
		school.put("A class", aClass);
		school.put("B class", bClass);
		
		aClass.add(new Student("01", "zhangdan"));
		aClass.add(new Student("02", "wangwu"));
		
		aClass.add(new Student("01", "lisi"));
		aClass.add(new Student("02", "xiaoming"));
	
		//遍历学校,获取班级
		Set<String> set = school.keySet();
		Iterator<String> iterator = set.iterator();
		while (iterator.hasNext()) {
			String classStr =  iterator.next();
			getStudentInfor(school.get(classStr));
		}
	}
	
	public static void getStudentInfor(List<Student> list){
		Iterator<Student> iterator = list.iterator();
		while (iterator.hasNext()) {
			Student student = (Student) iterator.next();
			sop(student.getId() + " ,name = "+student.getName());
		}
	}

打印结果:

01 ,name = zhangdan
02 ,name = wangwu
01 ,name = lisi
02 ,name = xiaoming
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值