关于Map的五种输出方式
构造一个HashMap<Integer,Pet>;构造一个TreeMap<Pet,String>其中Pet为自定义的类,表示我拥有的宠物类型
-
Pet属性:名称,数量,腿的个数
-
Pet方法: getter.setter,compare
-
Pet类实现接口Comparator,并实现方法compare来定义Pet的大小,从而在TreeMap中自然排序
-
- 其中用到了compareTo方法来比较String的大小
-
创建Pet类
import java.util.Comparator;
/**
* Created with IntelliJ IDEA.
*
* @Author: xuexuezi
* @Date: 2022/09/17/3:50
* @Description:
*/
public class Pet implements Comparator<Pet> {
//无参构造
public Pet(){
}
//有参构造
public Pet(String name,int num, int legNum){
this.name = name;
this.num = num;
this.legNum = legNum;
}
private String name;
private int num;
private int legNum;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public int getNum(){
return this.num;
}
public void setNum(int num){
this.num = num;
}
public int getLeg(){
return this.legNum;
}
public void setLeg(int legNum){
this.legNum = legNum;
}
//以名字大小决定宠物大小
@Override
public int compare(Pet o1, Pet o2) {
if(o1.name.compareTo(o2.name) > 0){//指定的数o1.name>参数o2.name,返回正数
return 1;//得出o1>o2.并排在o2后
}else if(o1.name.compareTo(o2.name) < 0){//指定的数o1.name<o2.name,返回负数
return -1;
}else{//相等返回0
return 0;
}
}
//不重写toString方法时,集合中打印自定义类都是散列码包含类名和地址,例如1=com.qx.day10.Pet@27ddd392
// @Override
// public String toString() {
// //return super.toString();
// return getClass().getName()+"[name = "+name+",num = "+num+",legNum = "+legNum+"]";
// }
- 构造一个HashMap<Integer,Pet>的map1
Pet pet1 = new Pet("边牧",1,4);
Pet pet2 = new Pet("缅因猫",2,4);
Pet pet3 = new Pet("鹦鹉",4,2);
Pet pet4 = new Pet("鲸鱼",1,0);
Map<Integer,Pet> map1 = new HashMap<Integer,Pet>();//该种宠物养了几只
map1.put(1,pet1);
map1.put(23,pet4);
map1.put(56,pet2);
map1.put(8,pet2);
map1.put(2,pet3);
- 构造一个一个TreeMap<Pet,String>的map2
注意:key为自定义类时,新建map的参数为创建一个自定义类的对象
//注意,以自定义的类为key时,需要在构造map时
Map<Pet,String> map2 = new TreeMap<Pet,String>(new Pet());//这类宠物性格特征
map2.put(pet1,"聪明");
map2.put(pet2,"温顺");
map2.put(pet3,"漂亮");
map2.put(pet4,"孤独");
遍历map
1.直接输出map的映射关系
- 导包
import java.util.HashMap;
- 由于对象直接输出会调用该类的toString方法,因为此处没有重写Object类的toString方法,所以输出对象会输出
类名+散列码
//1.直接遍历
System.out.println(map1);
System.out.println(map2);
输出结果如下:
{1=com.qx.day10.Pet@27ddd392, 2=com.qx.day10.Pet@19e1023e, 23=com.qx.day10.Pet@7cef4e59, 56=com.qx.day10.Pet@64b8f8f4, 8=com.qx.day10.Pet@64b8f8f4}
{com.qx.day10.Pet@64b8f8f4=温顺, com.qx.day10.Pet@27ddd392=聪明, com.qx.day10.Pet@7cef4e59=孤独, com.qx.day10.Pet@19e1023e=漂亮}
- 解决办法1:重写Object的toString方法后直接输出
@Override
public String toString() {
//return super.toString();
return getClass().getName()+"[name = "+name+",num = "+num+",legNum = "+legNum+"]";
}
输出结果如下:
{1=com.qx.day10.Pet[name = 边牧,num = 1,legNum = 4], 2=com.qx.day10.Pet[name = 鹦鹉,num = 4,legNum = 2], 23=com.qx.day10.Pet[name = 鲸鱼,num = 1,legNum = 0], 56=com.qx.day10.Pet[name = 缅因猫,num = 2,legNum = 4], 8=com.qx.day10.Pet[name = 缅因猫,num = 2,legNum = 4]}
{com.qx.day10.Pet[name = 缅因猫,num = 2,legNum = 4]=温顺, com.qx.day10.Pet[name = 边牧,num = 1,legNum = 4]=聪明, com.qx.day10.Pet[name = 鲸鱼,num = 1,legNum = 0]=孤独, com.qx.day10.Pet[name = 鹦鹉,num = 4,legNum = 2]=漂亮}
- 解决办法2:输出对象时,输出他的标志性属性例如名字
- 直接输出是自动输出键值对,无法做到
2. 用map.keySet()返回key的Set集合;再通过方法map.get(key)获得value
- 导包
import java.util.Set;
- 此时因为map1和map2的键值对中都包含对象,所以输出对象.name来代表对象,而不是放任其自动输出散列码
//2.使用map.keySet()方法把所有key存入Set集合,再根据map.get()方法,根据key取到value
Set<Integer> key1 = map1.keySet();
for(Integer k1: key1){//此处,key为个数直接输出,vaule为对象,直接输出对象是散列码,最好是输出对象的名称
System.out.println(k1+" = "+map1.get(k1).name);
}
Set<Pet> key2 = map2.keySet();
for(Pet k2: key2){//此处,key为对象,输出对象的名称比较好
System.out.println(k2.name+" = "+map2.get(k2));
}
3.使用map.entrySet()方法,并使用Entry类的Set集合存放所有键值对(Entry内部类可以接收一个键值对)
- 导包
import java.util.Map.Entry;
Entry内部类来表示一个映射项,映射项包含Key和Value
//3.遍历3
Set<Entry<Integer,Pet>> entrys = map1.entrySet();
System.out.println(entrys);
Set<Entry<Pet,String>> entryss = map2.entrySet();
System.out.println(entryss);
- 输出如下
[1=com.qx.day10.Pet@27ddd392, 2=com.qx.day10.Pet@19e1023e, 23=com.qx.day10.Pet@7cef4e59, 56=com.qx.day10.Pet@64b8f8f4, 8=com.qx.day10.Pet@64b8f8f4]
[com.qx.day10.Pet@64b8f8f4=温顺, com.qx.day10.Pet@27ddd392=聪明, com.qx.day10.Pet@7cef4e59=孤独, com.qx.day10.Pet@19e1023e=漂亮]
4.用增强for遍历Entry类型的Set,使用Entry的getKey()和getValue()方法
//4.遍历Entry类型的Set,使用Entry的getKey()和getValue()方法
Set<Entry<Integer,Pet>> entrys = map1.entrySet();
for(Entry<Integer,Pet> e: entrys){
System.out.println(e.getKey()+" = "+ e.getValue().name);
}
Set<Entry<Pet,String>> entryss = map2.entrySet();
for(Entry<Pet,String> e: entryss){
System.out.println(e.getKey().name +" = "+e.getValue());
}
5.通过 lambda 表达式使用 forEach()
Lambda 表达式
Lamba的语法格式如下:
parameters代表方法参数,expression代表方法返回值
(parameters) -> expression
或
(parameters) ->{ statements; }
Lambda 表达式的简单例子:
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
HashMap forEach() 方法
forEach() 方法用于对 HashMap 中的每个映射执行指定的操作。
forEach() 方法的语法为:
hashmap.forEach(BiConsumer<K, V> action)
注: hashmap 是 HashMap 类的一个对象。
action - 要执行的操作
Lambda表达式内k,v随意起名。只是代表map中每个键值对的key和value
- 遍历5.通过 lambda 表达式使用 forEach()
map1.forEach((k,v)->{
System.out.print(k+"="+v.getName()+" ");
});
System.out.println();
map2.forEach((k,v)->{//Lambda表达式内k,v随意起名。只是代表map中每个键值对的key和value
System.out.print("key:"+k.getName()+"="+"value:"+v+" ");
});