一、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();//返回字符串
}
}