------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Map派系
day18 01-常用对象API(集合框架-Map集合特点&常用方法)
1、Map在集合框架中的位置
2、Map与Collection同级,为顶层接口。Map集合的使用频率相当高。接口Map
3、Map集合与Collection集合的区别
①Map集合一次添加一对元素。Collection集合一次添加一个元素。
②Map也称为双列集合。Collection集合也称为单列集合。
其实Map集合中存储的就是键值对。K——Key(键),V——Value(值)。Map集合中必须保证键的唯一性!
4、Map接口常用方法,Map集合可以根据键来操作
(1)增
value put(key , value):返回前一个和key关联的值。如果没有,返回null。(可以理解为同时具备add和set的功能)
(2)删
void clear():清空map集合
value remove(key):根据指定的key删除这个键值对(不是单独删除键,是删除整个键值对)
(3)查
(3.1)判断
boolean containKey(key)
boolean containValue(value)
boolean isEmpty()
(3.2)获取
value get(key):通过键获取值,如果没有该键返回null。当然可以通过返回null,来判断是否包含指定键。
int size():获取键值对的个数。
day18 02-常用对象API(集合框架-Map集合-常用方法演示)
1、增,代码示例:
publicclass Demo38 {
public staticvoid main(String args[]){
Mapmap = newHashMap();
System.out.println(map.put(4,"张三"));
System.out.println(map.put(4,"李四"));
}
}
运行结果:null
张三
{4=李四}
2、不要忘记,value put(key , value):返回前一个和key关联的值。如果没有,返回null。(可以理解为同时具备add和set的功能)
3、键相同,值会覆盖。
4、删,代码示例:
publicclass Demo38 {
public staticvoid main(String args[]){
Mapmap = newHashMap();
map.put(3,"张三");
map.put(4,"李四");
map.put(5,"王五");
//删除
map.remove(4);
System.out.println(map);
}
}
运行结果:{3=张三, 5=王五}
5、查——判断,代码示例:
publicclass Demo38 {
public staticvoid main(String args[]){
Mapmap = newHashMap();
map.put(3,"张三");
map.put(4,"李四");
map.put(5,"王五");
System.out.println(map.containsKey(3));
System.out.println(map.containsValue("王五"));
}
}
运行结果:true
true
6、查——获取,代码示例:
publicclass Demo38 {
public staticvoid main(String args[]){
Mapmap = new HashMap();
map.put(3,"张三");
map.put(4,"李四");
map.put(5,"王五");
System.out.println(map.get(3));
System.out.println(map.get(10));
}
}
运行结果:张三
null
day18 03-常用对象API(集合框架-遍历Map集合1——keySet)
1、接口Map
Set
返回此映射中所包含的键的Set视图。
2、说白了,就是通过keySet()方法获得该Map集合中所有键的Set集合,再通过Set集合的迭代器拿到每一个键,最后用Map集合中的get(key)方法拿对应的值。Map没迭代器,那就先转化成有迭代器的集合,再用迭代器。
3、代码示例:
publicclass Demo38 {
public staticvoid main(String args[]){
Mapmap = newHashMap();
map.put(3,"张三");
map.put(4,"李四");
map.put(5,"王五");
//通过keySet方法拿到Map集合中所有键的集合
SetkeySet = map.keySet();
//通过Set集合的迭代器拿每一个键
Iteratorit = keySet.iterator();
while(it.hasNext()){
//通过get方法拿值
System.out.println(map.get(it.next()));
}
}
}
代码示例:李四
张三
王五
4、演示图解
day18 04-常用对象API(集合框架-遍历Map集合2——entrySet)
1、接口Map
public Set
返回此映射所包含的映射关系的Set视图。(返回的是结婚证,包含着丈夫也包含着妻子)
2、keySet是拿所有的丈夫。entrySet是拿所有的结婚证,有了结婚证,丈夫妻子你都能拿。
3、接口Map.Entry
方法摘要 |
|
boolean |
equals(Object o) |
K |
getKey() |
V |
getValue() |
int |
hashCode() |
V |
setValue(V value) |
4、代码示例
publicclass Demo46 {
public staticvoid main(String[] args) {
Mapmap = newHashMap();
map.put(3,"zhangsan");
map.put(4,"lisi");
map.put(5,"wangwu");
Set> set = map.entrySet();
Iterator> it = set.iterator();
while(it.hasNext()){
Map.Entry me = it.next();
Integerkey = me.getKey();
Stringvalue = me.getValue();
System.out.println(key+"...."+value);
}
}
}
运行结果:3....zhangsan
4....lisi
5....wangwu
5、演示图例
6、Map.Entry是Map接口的嵌套类。
接口Map
嵌套类摘要
static interface Map.Entry
映射项(键-值对)
7、为什么Entry非要定义在Map里面?放外面不行吗?
Entry是键和值的映射关系对象。因此,你必须先有Map映射。而Entry把关系封装成对象。这个关系在访问Map中的键和值。外部规则里有内部跪着,内部规则可以直接访问外部规则中的内容。内部类(或内部接口)。
day18 05-常用对象API(集合框架-遍历Map集合3——values)
1、接口Map
Collection
返回此映射中包含的值的Collection视图。(即只拿值)
2、为何他不是Set而是Collection?因为Key是唯一的,但value不一定唯一。
3、代码示例:
publicclass Demo46 {
public staticvoid main(String[] args) {
Mapmap = newHashMap();
map.put(3,"zhangsan");
map.put(4,"lisi");
map.put(5,"wangwu");
Collectionco = map.values();
Iteratorit = co.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
运行结果:zhangsan
lisi
wangwu
4、☆关于遍历Map集合的3个方式☆
(1)(返回一个键集合):通过Set
(2)(返回一个键值对映射集合):通过Set
(3)(返回一个值集合):通过Collection
day18 06-常用对象API(集合框架-Map集合——常见子类对象)
1、Map接口下常用的子类
|——HashTable:内部结构是哈希表,是同步的。不允许null作为键,不允许null作为值。
|——HashMap:内部结构是哈希表,是不同步的。允许null作为键,允许null作为值。
|——TreeMap:内部结构式二叉树,是不同步的。可以对Map集合中的键进行排序。
2、HashTable下有一个子类——Properties,使用频率相当高。Propertise类表示了一个持久的属性集。用来存储键值对性的配置文件信息。他可以和IO技术相结合。
day18 07-常用对象API(集合框架-Map集合——HashMap存储自定义对象)
1、需求:将学生对象和学生的归属地,通过键和值存储到Map集合中。如果两个Student对象的名字和年龄相同,则认为是同一个人。
2、代码示例一:该代码有问题
classStudent {
private String name;
private intage;
public Student(String name,int age){
this.name= name;
this.age= age;
}
public voidsetName(String name){
this.name= name;
}
public voidsetAge(int age){
this.age= age;
}
public String getName(){
return name;
}
public intgetAge(){
return age;
}
public String toString(){
return "name:"+name+"...age"+age;
}
}
publicclass AWTDemo05 {
public staticvoid main(String[] args) {
HashMaphm = newHashMap();
hm.put(new Student("lisi",38),"beijing");
hm.put(new Student("zhaoliu",24),"dalian");
hm.put(new Student("wangwu",24),"shenyang");
hm.put(new Student("lisi",38),"shanghai");
Setset = hm.keySet();
Iteratorit = set.iterator();
while(it.hasNext()){
Students = it.next();
System.out.println(s+"——"+hm.get(s));
}
}
}
运行结果:name:lisi...age38——beijing
name:wangwu...age24——shenyang
name:zhaoliu...age24——dalian
name:lisi...age38——shanghai
可以发现,lisi并没有被视为是同一个人。因为还没有覆盖Student类中的hashCode()方法和equals()方法。
3、代码示例二:此代码仍然有问题
classStudent {
private String name;
private intage;
public Student(String name,int age){
this.name= name;
this.age= age;
}
public voidsetName(String name){
this.name= name;
}
public voidsetAge(int age){
this.age= age;
}
public String getName(){
return name;
}
public intgetAge(){
return age;
}
public String toString(){
return "name:"+name+"...age"+age;
}
public inthashCode(){
return name.hashCode()+age;
}
}
publicclass AWTDemo05 {
public staticvoid main(String[] args) {
HashMaphm = newHashMap();
hm.put(new Student("lisi",38),"beijing");
hm.put(new Student("zhaoliu",24),"dalian");
hm.put(new Student("wangwu",24),"shenyang");
hm.put(new Student("lisi",38),"shanghai");
Setset = hm.keySet();
Iteratorit = set.iterator();
while(it.hasNext()){
Students = it.next();
System.out.println(s+"——"+hm.get(s));
}
}
}
运行结果:name:wangwu...age24——shenyang
name:zhaoliu...age24——dalian
name:lisi...age38——shanghai
name:lisi...age38——beijing
可以发现lisi仍然没有被视为是同一个人。因为Student中的hashCode()方法,是name.hashCode()+age;所以两个lisi算出的哈希值仍然相同。之后通过Student类中的equals()方法(这里也就是Object类中的equals()方法),比较是不同的地址值。所以仍被认为是不同的键。
4、代码示例三:该代码是正确的
classStudent {
private String name;
private intage;
public Student(String name,int age){
this.name= name;
this.age =age;
}
public voidsetName(String name){
this.name= name;
}
public voidsetAge(int age){
this.age =age;
}
public String getName(){
return name;
}
public intgetAge(){
return age;
}
public String toString(){
return "name:"+name+"...age"+age;
}
public inthashCode(){
return name.hashCode()+age;
}
public booleanequals(Object obj){
Students = (Student)obj;
return this.name.equals(s.name)&&(this.age==s.age);
}
}
publicclass AWTDemo05 {
public staticvoid main(String[] args) {
HashMap hm = new HashMap();
hm.put(new Student("lisi",38),"beijing");
hm.put(new Student("zhaoliu",24),"dalian");
hm.put(new Student("wangwu",24),"shenyang");
hm.put(new Student("lisi",38),"shanghai");
Setset = hm.keySet();
Iteratorit = set.iterator();
while(it.hasNext()){
Students = it.next();
System.out.println(s+"——"+hm.get(s));
}
}
}
运行结果:name:wangwu...age24——shenyang
name:zhaoliu...age24——dalian
name:lisi...age38——shanghai
哦了!!!事实证明,HashMap保证键的唯一性,用的也是先hashCode方法再equals方法。
day18 08-常用对象API(集合框架-Map集合——TreeMap存储自定义对象)
1、需求一:利用Student的自然排序,按照年龄从小到大,将Map集合中的Student对象元素进行排序。
2、代码示例:
classStudent implementsComparable{
private String name;
private intage;
public Student(String name,int age){
this.name= name;
this.age= age;
}
public voidsetName(String name){
this.name= name;
}
public voidsetAge(int age){
this.age= age;
}
public String getName(){
return name;
}
public intgetAge(){
return age;
}
public String toString(){
return "name:"+name+"...age"+age;
}
public intcompareTo(Object obj){
Students = (Student)obj;
return this.age-s.age;
}
}
publicclass AWTDemo06 {
public staticvoid main(String[] args) {
TreeMaptm = newTreeMap();
tm.put(new Student("lisi",38),"beijing");
tm.put(new Student("zhaoliu",24),"dalian");
tm.put(new Student("wangwu",55),"shenyang");
tm.put(new Student("zhangsan",38),"shanghai");
Set>set = tm.entrySet();
Iterator>it = set.iterator();
while(it.hasNext()){
Map.Entry me = it.next();
Students = me.getKey();
Stringstr = me.getValue();
System.out.println(s+"..."+str);
}
}
}
运行结果:name:zhaoliu...age24...dalian
name:lisi...age38...shanghai
name:wangwu...age55...shenyang
由于zhangsan和lisi年龄都是38岁,所以利用compareTo方法一比,返回值为0.则认为是重复的键。只保留前一个键。且值shanghai覆盖了原来的值beijing。
3、需求二:利用比较器,按照name的字母顺序,将Map集合中的Student对象元素进行排序。
4、代码示例:
classStudent implementsComparable{
private String name;
private intage;
public Student(String name,int age){
this.name= name;
this.age= age;
}
public voidsetName(String name){
this.name= name;
}
public voidsetAge(int age){
this.age= age;
}
public String getName(){
return name;
}
public intgetAge(){
return age;
}
public String toString(){
return "name:"+name+"...age"+age;
}
public intcompareTo(Object obj){
Students = (Student)obj;
return this.age-s.age;
}
}
classCompartorByName implementsComparator{
public intcompare(Object obj1,Object obj2){
Students1 = (Student)obj1;
Students2 = (Student)obj2;
return s1.getName().compareTo(s2.getName());
}
}
publicclass AWTDemo06 {
public staticvoid main(String[] args) {
TreeMaptm = newTreeMap(newCompartorByName());
tm.put(new Student("lisi",38),"beijing");
tm.put(new Student("zhaoliu",24),"dalian");
tm.put(new Student("wangwu",55),"shenyang");
tm.put(new Student("lisi",66),"shanghai");
Set>set = tm.entrySet();
Iterator>it = set.iterator();
while(it.hasNext()){
Map.Entry me = it.next();
Students = me.getKey();
Stringstr = me.getValue();
System.out.println(s+"..."+str);
}
}
}
运行结果:name:lisi...age38...shanghai
name:wangwu...age55...shenyang
name:zhaoliu...age24...dalian
由于有两个lisi,所以后面进来而被认为是重复的键。只保留之前的键。但值shanghai覆盖了原来的值beijing。
day18 09-常用对象API(集合框架-Map集合——LinkedHashMap)
1、LinkedHashMap,在保证键唯一的情况下,还可以保证键的有序性。(类似于LinkedHashSet集合)
2、代码示例:
publicclass AwtDemo07 {
public staticvoid main(String[] args) {
LinkedHashMaplhm = newLinkedHashMap();
lhm.put(1,"yi");
lhm.put(2,"er");
lhm.put(3,"san");
lhm.put(1,"yiyiyi");
Setset = lhm.keySet();
Iteratorit = set.iterator();
while(it.hasNext()){
Integeri = it.next();
System.out.println(i+"..."+lhm.get(i));
}
}
}
运行结果:1...yiyiyi
2...er
3...san
键相同,后面的值yiyiyi盖掉了原来的值yi。
day18 10-常用对象API(集合框架-Map集合练习——记录字母次数思路)
1、练习:"fdgavcbsacdfs",获取该字符串中每一个字符出现的次数。要求的打印结果是:
a(2)b(1)……
2、分析:很多人的想法是一个个遍历,再计数。但是我嫌麻烦。我发现,一个字母对应一个次数,如a(2)、b(1)。这之间有映射关系。既然如此,我们想到了数组。但数组中有映射的一方是有序编号。如果映射双方是无序的时候,这时就不能想数组了,想到Map集合。又发现,可以保证唯一性的一方具备着顺序,如a、b、c……因此可以使用TreeMap集合。
3、思路:
这个集合中最终应该存储的是字母和次数的对应关系。
(1)因为操作的是字符串中的字母,所以先将字符串变成字符数组。
(2)遍历字符数组,用每个字母作为键,去查Map集合这个表。
如果该字母键不存在,就将该字母作为键,1作为值存储到Map集合中。
如果该字母键存在,九江该字母键的对应值取出并+1。再将该字母和+1后的值存储到Map集合中。
键相同,值覆盖。这样就记录了该字母的出现次数。
(3)遍历结束,map集合就记录了所有字母出现的次数。
day18 11-常用对象API(集合框架-Map集合练习——记录字母次数代码)
1、代码示例
publicclass AwtDemo09 {
public staticvoid main(String[] args) {
Stringstr = "fdgavcbsacdfs";
Strings = getCharCount(str);
System.out.println(s);
}
public staticString getCharCount(String str){
//将字符串变成字符数组
char[] chs = str.toCharArray();
//定义map集合
Mapmap = newTreeMap();
//遍历字符数组
for(inti=0;i map){
StringBuildersb = new StringBuilder();
Iteratorit = map.keySet().iterator();
while(it.hasNext()){
Characterkey = it.next();
Integervalue= map.get(key);
sb.append(key+"("+value+")");
}
return sb.toString();
}
}
运行结果:a(2)b(1)c(2)d(2)f(2)g(1)s(2)v(1)
2、扩展内容,我字符串里来了许多乱七八糟的东西,比如他成了"fdg+avc bsac-dfs"。我想要别的,只要字母。
在遍历字符数组的for循环中加一个判断,
if(!(chs[i]>='a'&&chs[i]<='z'||chs[i]>='A'&&chs[i]<='z')){
continue;
}
搞定。
day18 12-常用对象API(集合框架-Map集合练习——Map查表法)
1、Map在有映射关系时,可以优先考虑。其在查表法中的应用较为多见。
2、输入数字,之后星期几的程序
//原来的数组写法
public staticString getWeek(intweek){
if(week<1||week>7){
throw newRuntimeException("没有对应的兴起,请您重新输入");
}
String[]weeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
return weeks[week];
}
//Map写法
public staticString getWeekByMap(String week){
Mapmap = new HashMap();
map.put(1,"星期一");
map.put(2,"星期二");
map.put(3,"星期三");
map.put(4,"星期四");
map.put(5,"星期五");
map.put(6,"星期六");
map.put(7,"星期日");
return map.get(week);
}
3、另外提醒,Map中的值可以是一个集合。因为集合也是对象。