天天看点

Lesson_for_java_day14--java中的集合——Map、HashMap、TreeMap

一、Map的讲解

Demo1:

package map;

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

/*
	Map集合:该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
		1、添加:
			put(key,value);
			putAll(Map<? extends K,? extends v> m);
		2、判断:
			boolean containsKey();
			boolean containsValue()
			isEmpty();
		3、删除:
			void clear();
			remove(key);
		4、获取:
			get(key)
			size();
			values();
			
			entrySet();
			keySet();
			
	Map:
		|--Hashtable:底层是哈希表数据结构,不可以存入null键和null值。该集合是线程同步的。JDK1.0.效率低。
		|--HashMap:底层是哈希表数据结构,允许使用null键和null值,该集合是不同步的。JDK1.2.效率高。
		|--TreeMap:底层是二叉树数据结构。线程不同步,可以用于给Map集合中的键进行排序。
		
	和Set很像。其实Set底层就是用了Map集合。
 */
public class MapDemo {
	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String,String>();
		
		//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应的值。
		//并put方法会返回被覆盖的值。		
		System.out.println("put:" + map.put("01", "zhangsan1"));
		System.out.println("put:" + map.put("01", "wangwu1"));
		map.put("02", "zhangsan2");
		map.put("03", "zhangsan3");
		
		System.out.println("containsKey:" + map.containsKey("02"));
		System.out.println("remove:" + map.remove("02"));
		System.out.println("get:" + map.get("01"));
		
		//可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断
		map.put(null, "05");
		map.put("04", null);
		System.out.println("get:" + map.get("04"));
		
		//获取Map集合中所以的值
		Collection<String> coll = map.values();
		System.out.println(coll);
		
		System.out.println(map);
	}
}
           

Demo2:

package map;

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

/*
	Map集合的两种取出方式:
		1、Set<K> keySet:将Map中所有的键存入到Set集合。因为set具备迭代器。
			所有可以迭代方式取出所有的键,再根据get方法,获取每一个键对应的值。
			
			Map集合的取出原理:将map集合转成set集合,再通过迭代器取出。
		2、Set<Map.Entry<K,V>> entrySet:将map集合中的映射关系存入到set集合中,
			而这个关系的数据类型就是Map.Entry.
 */
/*
	Map.Entry:其实Entry也是一个接口,它是Map接口中的一个内部接口。
	
interface Map{
	public static interface Entry{
		public abstract Object getKey();
		public abstract Object getValue();
	}
}

class HashMap implements Map{
	class Hash implements Map.Entry{
		public Object getKey(){}
		public Object getValue(){}
	}
}
 */


public class MapDemo2 {
	public static void main(String[] args) {
		
		Map<String,String> map = new HashMap<String,String>();
		
		map.put("02", "zhangsan2");
		map.put("03", "zhangsan3");
		map.put("01", "zhangsan1");
		map.put("04", "zhangsan4");
		
		//方式二:
		//将map集合中的映射关系取出,存入到set集合中。
		Set<Map.Entry<String, String>> entrySet = map.entrySet();
		Iterator<Map.Entry<String, String>> it = entrySet.iterator();
		while(it.hasNext()){
			Map.Entry<String, String> me = it.next();
			String key = me.getKey();
			String value = me.getValue();
			System.out.println("key:" + key + ",value:" + value);
		}
				
		/*方式一:
		//先获取map集合的所有键的set集合,可以keySet();
		Set<String> keySet = map.keySet();
		
		//有了Set集合,就可以获取其迭代器
		for(Iterator<String> it = keySet.iterator(); it.hasNext();){
			String key = it.next();
			//有了键可以通过map集合的get方法获取其对应的值。
			String value = map.get(key);
			System.out.println("key:" + key + ",value:" + value);
		}
		*/
	}
}
           

Demo3:

package map;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/*
	map扩展知识:
		map集合被使用是因为具备映射关系。
		
	eg:
		方式一:学校集合中有班级与学生的映射关系,班级集合中有学号与学生姓名的映射关系
			"yureban" "01" "zhangsan"
			"yureban" "02" "lisi"
			
			"jiuyeban" "01" "wangwu"
			"jiuyeban" "02" "zhaoliu"
			
		方式二:学校集合中有班级与学生的映射关系,班级集合中有封装的学生对象
			"yureban" Student("01" "zhangsan")
			"yureban" Student("02" "lisi")
			
			"jiuyeban" Student("01" "wangwu")
			"jiuyeban" Student("02" "zhaoliu")
 */
public class MapDemo3 {
	public static void main(String[] args) {
		System.out.println("=======方式一:======");
		method_1();
		
		System.out.println("\n=======方式二:======");
		method_2();
	}
	
	//方式二:学校集合中有班级与学生的映射关系,班级集合中有封装的学生对象
	public static void method_2(){
		HashMap<String,List<Student1>> school = new HashMap<String,List<Student1>> ();//创建学校集合
		List<Student1> yure = new ArrayList<Student1>();//创建班级集合
		List<Student1> jiuye = new ArrayList<Student1>();
		
		school.put("yureban", yure);//将班级元素添加到学校集合中(映射关系)
		school.put("jiuye", jiuye);
		
		yure.add(new Student1(01,"zhangsan"));//将学生对象添加到班级集合中(没有映射关系)
		yure.add(new Student1(03,"lisi"));
		yure.add(new Student1(02,"wangwu"));
		
		jiuye.add(new Student1(01,"xiaozhang"));
		jiuye.add(new Student1(02,"xiaowang"));
		jiuye.add(new Student1(03,"xiaoli"));
			
		//遍历school集合,获取所有教室
		Iterator<String> it = school.keySet().iterator();
		while(it.hasNext()){//采用循环嵌套循环的方式
			String roomName = it.next();
			List<Student1> room = school.get(roomName);
			System.out.println("-----" + roomName + "-----" );
			
			//遍历教室集合,获取所有学生对象
			Iterator<Student1> it1 = room.iterator();
			while(it1.hasNext()){
				Student1 student = it1.next();
				System.out.println(student);
			}
		}
	}
	
	//方式一:学校集合中有班级与学生的映射关系,班级集合中有学号与学生姓名的映射关系
	public static void method_1(){
		HashMap<String,HashMap<String,String>> school = new HashMap<String,HashMap<String,String>>();//创建学校集合
		HashMap<String,String> yure = new HashMap<String,String>();//创建班级集合
		HashMap<String,String> jiuye = new HashMap<String,String>();
		
		yure.put("01", "zhangsan");//将班级元素添加的学校集合中(映射关系)
		yure.put("02", "lisi");
		
		jiuye.put("01", "wangwu");//将学生元素添加到班级集合中(映射关系)
		jiuye.put("02", "zhaoliu");
		
		school.put("yureban", yure);
		school.put("jiuyeban", jiuye);
		
		
		//遍历school集合,获取所有班级。
		Iterator<String> it = school.keySet().iterator();
		while(it.hasNext()){
			String roomName = it.next();
			HashMap<String,String> room = school.get(roomName);
			System.out.println("-----" + roomName + "-----" );
			//getStudentInfo(room);
			
			//遍历班级集合,获取学生的id和姓名
			Iterator<String> it1 = room.keySet().iterator();
			while(it1.hasNext()){
				String id = it1.next();
				String name = room.get(id);
				System.out.println(id + ": " + name);
			}
		}
	}
}


//创建学生类
class Student1{
	private String name;
	private int id;
	Student1(){
		
	}
	Student1(int id,String name){//重载构造方法
		this.id = id;
		this.name = name;
	}
	
	@Override
	public String toString() {//复写toString方法
		return id + ": " + name;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}	
}
           

练习一:

package map.test;

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

/*
	练习:
		每一个学生都有对应的归属地。
		学生Student,地址String
		学生属性:姓名,年龄。
		注意:姓名和年龄相同的视为同一个学生,保证学生的唯一性。
		
		思路:
			1、描述学生。
			2、定义map容器。将学生作为键,地址作为值,存入。
			3、获取map集合中的元素。
 */
public class MapTest {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Map<Student,String> map = new HashMap<Student,String>();
		map.put(new Student("zhangsan1",21), "beijing");
		map.put(new Student("zhangsan3",23), "shenzhen");
		map.put(new Student("zhangsan3",23), "tianjing");
		map.put(new Student("zhangsan4",24), "xiamen");
		map.put(new Student("zhangsan2",22), "shanghai");
		
		System.out.println("----------------第一种获取方式--------------");
		//方式一:
		Set<Student> set = map.keySet();
		Iterator<Student> it = set.iterator();
		while(it.hasNext()){
			Student s = it.next();		
			System.out.println(s + ",地址:" + map.get(s));
		}
		
		System.out.println("----------------第二种获取方式--------------");
		//方式二:
		Set<Map.Entry<Student, String>> set1 = map.entrySet();
		Iterator<Map.Entry<Student, String>> it1 = set1.iterator();
		while(it1.hasNext()){
			Map.Entry<Student, String> me = it1.next();
			Student s1 = me.getKey();
			String addr = me.getValue();
			System.out.println(s1 + ",地址:" + addr);
			
		}	
	}
}

class Student implements Comparable<Student>{
	private String name;
	private int age;
	
	Student(){
		
	}
	Student(String name,int age){
		this.name = name;
		this.age = age;
	}
		
	@Override
	public String toString() {
		return "Student: 姓名:" + name + ", 年龄:" + age ;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	public int compareTo(Student o) {
		// TODO Auto-generated method stub
		int num = new Integer(age).compareTo(new Integer(o.getAge()));
		if(num == 0)
			return this.getName().compareTo(o.getName());
		return num;
	}
	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;
	}	
}
           

练习二:

package map.test;

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

/*
	练习:
		需求:对学生对象的年龄进行升序排序。
		因为数据是以键值对形式存在的,所以要使用可以排序的Map集合。TreeMap.
 * 
 */
public class MapTest2 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuNameComparator());
		tm.put(new Student("zhangsan4",21), "beijing");
		tm.put(new Student("zhangsan3",23), "shenzhen");
		tm.put(new Student("zhangsan3",24), "wuhan");
		tm.put(new Student("zhangsan1",24), "xiamen");
		tm.put(new Student("zhangsan2",22), "shanghai");
		
		//按照学生的年龄进行排序
		Set<Map.Entry<Student,String>> entrySet = tm.entrySet();
		Iterator<Map.Entry<Student,String>> it = entrySet.iterator();
		while(it.hasNext()){
			Map.Entry<Student,String> me = it.next();
			Student s = me.getKey();
			String addr = me.getValue();
			System.out.println(s + " ,地址:" + addr);
		}	
	}
}

class StuNameComparator implements Comparator<Student>{

	public int compare(Student o1, Student o2) {
		// TODO Auto-generated method stub
		int num = o1.getName().compareTo(o2.getName());
		if(num == 0)
			return new Integer(o1.getAge()).compareTo(new Integer(o2.getAge()));
		return num;
	}

}
           

练习三:

package map.test;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/*
	练习:
		"abhdehodahbdodscndhwhshdls"获取该字符串中的字母出现次数。
			希望打印的结果是:a(1) c(2).......
	思路:
		通过结果发现,每个字母都有对应的次数。说明字母和次数之间都有映射关系。
		注意:当发现有映射关系时,可以选择map集合。因为map集合中存放的就是映射关系。
		
	什么时候使用map集合呢?
		当数据之间存在映射关系时,首先就要想到map集合。
		
	思路:
		1、将字符串转换成字符数组,因为要对每一个字母进行操作。
		2、定义一个map集合,因为打印结果的字母有顺序,所以使用TreeMap集合。
		3、遍历字符数组,将每一个字母作为键去查map集合,如果返回空,就将该字母和1存入到map集合中,如果返回不是空,
			说明该字母在map集合内已经存在,并有对应的次数,那么就获取该次数并进行自增,然后将该字母和自增后的次数存入
			到集合中,覆盖掉原来所对应的值。
		4、将map集合中的数据变成指定的字符串返回。
		
 */
public class MapTest3 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String s = charCount("abhdeh78odahbd51odscndhwh/.,shdls");
		System.out.println(s);
	}
	
	public static String charCount(String str){
		char[] ch = str.toCharArray();//将字符串转换成字符数组
		TreeMap<Character,Integer> map = new TreeMap<Character,Integer>();//定义一个TreeMap集合,存储字符并计数
		int count = 0;
		
		//遍历字符数组
		for(int i = 0; i < ch.length; i++){		
			//判断是否是字符,如果不是,跳出此次循环,进入下一个字符,次字符不计数
			if(!(ch[i] >= 'a' && ch[i] <= 'z' || ch[i] >='A' && ch[i] <= 'Z'))
				continue;
			
			Integer value = map.get(ch[i]);
			
			//判断字符并存储:方式二:
			if(value != null)
				count = value;
			count++;
			map.put(ch[i], count);
			count = 0;
			
			
			/*//判断字符并存储:方式一:
			if(value == null)
				map.put(ch[i], 1);
			else
				map.put(ch[i], value + 1);
			*/
		}
		//System.out.println(map);//打印集合内容
		
		//修改集合内元素的输出方式
		StringBuilder sb = new StringBuilder();//定义一个StringBuilder,用来存储字符数组内的每个元素
		Set<Map.Entry<Character,Integer>> entrySet = map.entrySet();//定义一个集合
		Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();//定义一个迭代器
		while(it.hasNext()){//获取迭代器里面的内容,并添加到StringBuilder中
			Map.Entry<Character,Integer> me = it.next();
			Character c = me.getKey();
			Integer i = me.getValue();
			sb.append(c + "(" + i + ") ");	
		}
		
		return sb.toString();//返回字符串
	}
}