黑马程序员_Map<K,V> 映射关系 Map.Entry
本文转自:http://rose20072011.blog.163.com/blog/static/1123361002013514111537286/
/*Map集合:存储键值对。要保证键的唯一性。
添加
put(K key,V value)
putAll(Map<? extends K,? extends V> m)
删除
clear()
remove(Object key)
判断
containsValue(Object value)
containsKey(Object key)
isEmpty()
获取
get(Object key)
size()
values()
Map:
Hashtable(JDK1.0)
底层数据结构是哈希表。不可存null键null值。线程同步,效率低。
HashMap(JDK1.2)
底层数据结构是哈希表。允许存入null键null值。不同步,效率高。
TreeMap
底层数据结构是二叉树。线程不同步。可用于给map集合中的键排序。
Map和Set和像,其实Set底层就是使用了Map集合。
map集合的两种取出方式:
1 Set<K> keySet
keySet将所有键取出,存入Set集合,因为Set具备迭代器。
可以用迭代器取出所有键,然后用get方法获取对应值
原理:map集合转成Set集合,再用迭代器取出。
2 Set<Map.Entry<K,V>> entrySet
entrySet将映射关系(Map.Entry类型)取出,存入Set集合,然后用
Map.Entry中的getKey和getValue获取键和值。
其实Entry是Map接口的一个内部接口,即子接口
先有Map集合再有映射关系,是Map集合的内部事务
Map.Entry中存的是映射关系这种数据类型。
内部接口才能加静态修饰符
interface Map
{
public static interface Entry
{
public abstract Object getKey();
public abstract Object getValue();
}
}
class HashMap implements Map
{
class Hashs implements Map.Entry
{
public Object getKey(){}
public Object getValue(){}
}
}
*/
import java.util.*;
//基本方法演示
class MapDemo1
{
public static void main(String[] args)
{
Map<String,String> map=new HashMap<String,String>();
//添加元素
map.put("01","zhangsan1");
map.put("02","zhangsan2");
//添加的键重复时,键对应的新值覆盖旧值,put方法返回旧值
System.out.println("put"+map.put("03","zhangsan3"));
System.out.println("put"+map.put("03","wangwu"));
//判断是否含有05键
System.out.println("containsKey:"+map.containsKey("05"));
/*也可通过get方法的返回值来判断一个键是否存在
存在会获取具体值,不存在就返回null。
HashMap支持null,Hashtable不支持null。
*/
map.put("04",null);
System.out.println("get:"+map.get("023"));
//删除02键并返回其对应的值
System.out.println("remove:"+map.remove("02"));
//获取map集合中所有的值。
Collection<String> coll=map.values();
System.out.println(coll);
System.out.println(map);
}
}
//keySet方法演示
class MapDemo2
{
public static void main(String[] args)
{
Map<String,String> map=new HashMap<String,String>();
//添加元素
map.put("04","zhangsan4");
map.put("02","zhangsan2");
map.put("01","zhangsan1");
map.put("03","zhangsan3");
//keySet()获取map集合的所有键,存入Set集合
Set<String> keySet=map.keySet();
//有了Set集合,就可获取迭代器
Iterator<String> it=keySet.iterator();
while(it.hasNext())
{
String key=it.next();
//map集合的get方法获取键对应的值
String value=map.get(key);
System.out.println("key:"+key+",value:"+value);
}
}
}
//entrySet方法演示
class MapDemo3
{
public static void main(String[] args)
{
Map<String,String> map=new HashMap<String,String>();
//添加元素
map.put("04","zhangsan4");
map.put("02","zhangsan2");
map.put("01","zhangsan1");
map.put("03","zhangsan3");
//取出映射关系,存入Set集合
Set<Map.Entry<String,String>> entrySet=map.entrySet();
//迭代器获取映射关系
Iterator<Map.Entry<String,String>> it=entrySet.iterator();
while (it.hasNext())
{
//Map.Entry中存的是映射关系
Map.Entry<String,String> me=it.next();
//获取键和值
String key = me.getKey();
String value = me.getValue();
System.out.println(key+":"+value);
}
}
}
/*
每个学生都有对应的归属地。
学生Student,地址String
学生属性:姓名,年龄
注意:姓名和年龄都相同的视为同一个学生
保证学生的唯一性。
1 描述学生
2 定义map容器,将学生作为键,地址作为值存入
3 获取map集合的元素
*/
import java.util.*;
//处理元素被存入二叉树时的情况
//实现Comparable,覆盖compareTo方法。
class Student implements Comparable<Student>
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public int compareTo(Student s)
{
int num=new Integer(this.age).compareTo(new Integer(s.age));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
//元素若被存入哈希表结构,要保证元素唯一性,
//就要覆盖两个方法hashCode和equals
public int hashCode()
{
return name.hashCode()+age*34;
}
public boolean equals(Object obj)
{
//扔进去的不是学生时,比较无意义
//于是直接抛异常
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s=(Student)obj;
return this.name.equals(s.name)&& this.age==s.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name+":"+age;
}
}
class MapDemo
{
public static void main(String[] args)
{
HashMap<Student,String> h=new HashMap<Student,String>();
//添加元素。学生是键,归属地为值
h.put(new Student("zhangsan1",21),"beijing");
h.put(new Student("zhangsan2",30),"hefei");
h.put(new Student("zhangsan2",30),"nanjing");
h.put(new Student("zhangsan3",27),"guangzhou");
h.put(new Student("zhangsan4",25),"qingdao");
//第一种取出方式 keySet
//keySet()获取map集合的所有键,存入Set集合
Set<Student> keySet=h.keySet();
//有了Set集合,就可获取迭代器
Iterator<Student> it=keySet.iterator();
while(it.hasNext())
{
Student stu=it.next();
//map集合的get方法获取键对应的值
String adrs=h.get(stu);
System.out.println(stu+":"+adrs);
}
//第二种取出方式 entrySet
//取出映射关系,存入Set集合
Set<Map.Entry<Student,String>> entrySet=h.entrySet();
//迭代器获取映射关系
Iterator<Map.Entry<Student,String>> it1=entrySet.iterator();
while (it1.hasNext())
{
//Map.Entry中存的是映射关系
Map.Entry<Student,String> me=it1.next();
//获取键和值
Student stu = me.getKey();
String adrs = me.getValue();
System.out.println(stu+"....."+adrs);
}
}
}
/*第16天第07集
对学生对象的年龄进行升序排序
因为数据是以键值对形式存在的,
所以要使用可以排序的TreeMap集合
*/
import java.util.*;
//处理元素被存入二叉树时的情况
//实现Comparable,覆盖compareTo方法。
class Student implements Comparable<Student>
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public int compareTo(Student s)
{
int num=new Integer(this.age).compareTo(new Integer(s.age));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
//元素若被存入哈希表结构,要保证元素唯一性,
//就要覆盖两个方法hashCode和equals
public int hashCode()
{
return name.hashCode()+age*34;
}
public boolean equals(Object obj)
{
//扔进去的不是学生时,比较无意义
//于是直接抛异常
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s=(Student)obj;
return this.name.equals(s.name)&& this.age==s.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name+":"+age;
}
}
//定义了一个比较器,此比较器是按照姓名排序。
class StuNameComaprator implements Comparator<Student>
{
public int compare(Student s1,Student s2)
{
int num = s1.getName().compareTo(s2.getName());
if(num==0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
return num;
}
}
class MapDemo
{
public static void main(String[] args)
{
TreeMap<Student,String> tm=new TreeMap<Student,String>(new StuNameComaprator());
tm.put(new Student("lisi4",21),"beijing");
tm.put(new Student("zhangsan2",30),"hefei");
tm.put(new Student("zhangsan2",30),"nanjing");
tm.put(new Student("zhangsan1",27),"guangzhou");
tm.put(new Student("abu3",25),"qingdao");
Set<Map.Entry<Student,String>> entrySet=tm.entrySet();
//迭代器获取映射关系
Iterator<Map.Entry<Student,String>> it=entrySet.iterator();
while (it.hasNext())
{
//Map.Entry中存的是映射关系
Map.Entry<Student,String> me=it.next();
//获取键和值
Student stu = me.getKey();
String adrs = me.getValue();
System.out.println(stu+"....."+adrs);
}
}
}
/*Map集合练习一:
"sdfgzxcvasdfxcvdf"获取该字符串中字母出现的次数
希望打印结果:a(1)c(2).....
分析:每个字母都有对应的次数
说明字母和次数之间有映射关系
于是可以选择map集合,因为map集合存放的就是映射关系。
1 将字符串转成字符数组,因为要对每一个字母进行操作。
2 定义一个map集合。因为打印结果时字母是有顺序的,所以使用TreeMap
3 遍历字符数组
将每个字母作为键去查map集合,
如果返回null,将该字母和1存入map集合中
如果返回不为null,说明map集合中存在该字母键并有对应次数
于是获取次数并自增,然后将字母和新的次数存入map集合中,覆盖原有值。
4 将map集合中的数据变成指定的字符串形式返回
*/
import java.util.*;
class MapDemo
{
public static void main(String[] args)
{
String s=charCount("sdfgzxcvasdfxcvdf");
System.out.println(s);
}
public static String charCount(String str)
{
char[] chs=str.toCharArray();
TreeMap<Character,Integer> tm=new TreeMap<Character,Integer>();
int count=0;
//遍历字符串
for (int x=0;x<chs.length;x++ )
{
/*把字母作为一个键到map集合中查找,
如果不存在,就添加键和值
如果存在,值自增1后存入
*/
//只要显示字母的次数,判断一下字符
if(!(chs[x]>='a'&& chs[x]<='z'|| chs[x]>='A'&& chs[x]<='z'))
continue;
Integer value=tm.get(chs[x]);
if (value!=null)
count=value;
count++;
tm.put(chs[x],count);
count=0;//count每次用完要清零
/*
if (value==null)
{
tm.put(chs[x],1);
}
else
{
value=value+1;
tm.put(chs[x],value);
}
*/
}
System.out.println(tm);//可省去,是为了看效果
StringBuilder sb=new StringBuilder();
Set<Map.Entry<Character,Integer>> entrySet=tm.entrySet();
//迭代器获取映射关系
Iterator<Map.Entry<Character,Integer>> it=entrySet.iterator();
while (it.hasNext())
{
Map.Entry<Character,Integer> me=it.next();
//获取键和值
Character ch = me.getKey();
Integer value = me.getValue();
sb.append(ch+"("+value+")");
}
return sb.toString();
}
}
/*Map集合练习二:map扩展
一对多映射
yureban 01 zhangsan
yureban 02 lisi
jiuyeban 01 wangwu
jiuyeban 02 zhaoliu
一个学校有多个教室,教室有对应名称
教室里有多人
*/
//思路一代码演示
import java.util.*;
class MapDemo1
{
public static void main(String[] args)
{
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>();
school.put("yureban",yure);
school.put("jiuyeban",jiuye);
yure.put("01","zhangsan");
yure.put("02","lisi");
jiuye.put("01","zhaoliu");
jiuye.put("02","wangwu");
//遍历学校,获取所有教室
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);
}
}
public static void getStudentInfo(HashMap<String,String> roomMap)
{
Iterator<String> it=roomMap.keySet().iterator();
while (it.hasNext())
{
String id=it.next();
String name=roomMap.get(id);
System.out.println(id+":"+name);
}
}
}
//思路二代码演示
//将人封装成对象,具备编号和姓名两个属性
class Student
{
private String id;
private String name;
Student(String id,String name)
{
this.id=id;
this.name=name;
}
public String toString()
{
return id+":"+name;
}
}
class MapDemo2
{
public static void main(String[] args)
{
demo();
}
public static void demo()
{
HashMap<String,List<Student>> school=new HashMap<String,List<Student>>();
List<Student> yure=new ArrayList<Student>();
List<Student> jiuye=new ArrayList<Student>();
//给教室赋名称
school.put("yureban",yure);
school.put("jiuyeban",jiuye);
//往教室添加学生对象
yure.add(new Student("01","zhangsan"));
yure.add(new Student("02","lisi"));
jiuye.add(new Student("01","wangwu"));
jiuye.add(new Student("02","zhaoliu"));
//遍历学校,获取所有教室
Iterator<String> it=school.keySet().iterator();
while (it.hasNext())
{
String roomName=it.next();
List<Student> room=school.get(roomName);
System.out.println(roomName);
//遍历教室,获取学生
getInfo(room);
}
}
public static void getInfo(List<Student> list)
{
Iterator<Student> it=list.iterator();
while (it.hasNext())
{
Student s=it.next();
System.out.println(s);
}
}
}