基于Map集合重点整理
Map集合
1.1Map集合概念
- Map集合是一种存放关系对象的对象的双列集合。
1.2Map集合的常用子类
HashMap<K,V>
- 1.数据存储方式:哈希表结构。
- 2.存储情况:无序性
- 3.保证键的唯一性方式:需要重写键的hashCode()方法、equals()方法。
LinkedHashMap<K,V>,是HashMap的一个子类。
- 1.数据存储方式:哈希表结构+链表结构
存储数据采用的哈希表结构+链表结构。
(1.链表结构:保证元素的存取顺序一致。
(2.哈希表结构:保证的键的唯一、不重复。 - 3.同样需要重写键的 hashCode()方法、equals()方法。
注意:K, V泛型类型可以一致,也可以不一致。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author lx
* @date 2019/1/3 - 17:25
* public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。
* public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
* public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
* boolean containsKey(Object key) 判断集合中是否包含指定的键。
* public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。
* public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)
*/
public class HashMapDemo {
public static void main(String[] args) {
HashMap<String, String> hashMap = new HashMap<>();
//添加元素
hashMap.put("冯小刚", "范冰冰");
hashMap.put("李晨", "范冰冰");
//如果键相同,值不同时,直接会覆盖前面的Value值。
hashMap.put("冯小刚", "徐帆");
hashMap.put("冯绍峰", "赵丽颖");
hashMap.put("霍建华", "林心如");
hashMap.put("杨幂", "刘恺威");
System.out.println(hashMap);
//{冯绍峰=赵丽颖, 霍建华=林心如, 冯小刚=徐帆, 李晨=范冰冰, 杨幂=刘恺威}
//通过Key删除元素
hashMap.remove("杨幂");
System.out.println(hashMap);
//{冯绍峰=赵丽颖, 霍建华=林心如, 冯小刚=徐帆, 李晨=范冰冰}
//获取指定键key的value值
String s = hashMap.get("霍建华");
System.out.println(s);//林心如
//判断集合中是否包含指定键
System.out.println(hashMap.containsKey("杨幂"));//在这之前已经被删除了,返回false
//判断集合中是否含有指定value值(一般很少用)
System.out.println(hashMap.containsValue("范冰冰"));//true
//获取集合中的所有键,并存储到集合中
Set<String> set=hashMap.keySet();
System.out.println(set);//[冯绍峰, 霍建华, 冯小刚, 李晨]
//获取 键值对 对象的集合
Set<Map.Entry<String,String>> set1=hashMap.entrySet();
System.out.println(set1);//[冯绍峰=赵丽颖, 霍建华=林心如, 冯小刚=徐帆, 李晨=范冰冰]
//遍历获取到的键值对的集合
for (Map.Entry<String,String> ss:set1) {
System.out.println(ss);
/*
冯绍峰=赵丽颖
霍建华=林心如
冯小刚=徐帆
李晨=范冰冰
*/
}
}
}
Entry键值对对象
- Key(键)+Value(值)=Map集合中的Entry项。
- Entry将键值对封装成了键值对 对象。方便了我们从每一个Entry对象中获取对应的键与对应的值。
Map集合遍历键值对的方式
通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。
- 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。使用entrySet()方法。
- 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
- 通过键值对(Entry)对象,获取Entry对象中的键与值。使用getkey() 方法和getValue()。
package hashMap_demo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* public K getKey() :获取Entry对象中的键。
* public V getValue() :获取Entry对象中的值。
* 在Map集合中也提供了获取所有Entry对象的方法:
* public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)
*/
public class EntryDemo {
public static void main(String[] args) {
HashMap<Integer, String> map = new HashMap<>();
map.put(20, "aa");
map.put(18, "bb");
map.put(20, "dd");
map.put(25, "gg");
map.put(28, "cc");
// 使用hashMap集合对象调用entrySet方法获取Set的所有的entry对象,
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
int aInt = entry.getKey();
String ss = entry.getValue();
System.out.println(aInt + "cp是" + ss);
//输出结果:
//18cp是bb
//20cp是dd
//25cp是gg
//28cp是cc
//Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了
}
}
}
HashMap存储自定义类型键值
- 练习:每位学生(姓名,年龄)都有自己的家庭住址。
- 那么,既然有对应关系,则将学生对象和家庭住址存储到 map集合中。学生作为键, 家庭住址作为值。
- 注意,学生姓名相同并且年龄相同视为同一名学生。
package hashMap_demo;
import java.util.Objects;
/**
* @author lx
* @date 2019/1/13 - 18:15
*/
public class Student {
//创建变量
private String name;
private int age;
//默认构造器
public Student() {
}
//有参构造器
public Student(String name, int age) {
this.name=name;
this.age=age;
}
//setter getter方法
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setAge() {
this.age = age;
}
//equals方法首先判断传入的是否与本类中的相同,相同则返回true
public boolean equals(Object o) {
if (this == o) {
return true;
}//其次再判断如果为空或者类名不同,则直接返回false
if (o == null || getClass() != o.getClass()) {
return false;
}
//将Object类型强转为Student类型,构成内容给的比较
Student student = (Student) o;
return age == student.age && Objects.equals(name, age);
}
//重写toString方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//保证键值的唯一性
@Override
public int hashCode() {
return Objects.hash(name,age);
}
}
定义测试类:
package hashMap_demo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author lx
* @date 2019/1/13 - 18:39
*/
public class Entry_Demo {
public static void main(String[] args) {
Map<Student,String> map=new HashMap<>();
map.put(new Student("赵颖", 20), "河北");
map.put(new Student("陈爽", 25), "湖南");
map.put(new Student("张亚蓝", 29), "厦门");
map.put(new Student("吕小童", 32), "陕西");
map.put(new Student("赵颖",20),"山西");
Set<Student> studentSet=map.keySet();
for (Student key:studentSet
) {
String sss = map.get(key);
System.out.println(key+"的住址是"+sss);
/*输出结果:
Student{name='赵颖', age=20}的住址是山西
Student{name='陈爽', age=25}的住址是湖南
Student{name='吕小童', age=32}的住址是陕西
Student{name='张亚蓝', age=29}的住址是厦门*/
}
}
}
1.当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法。
2.如果要保证map中存放的key和取出的顺序一致,可以使用 java.util.LinkedHashMap 集合来存放。
LinkedHashMap
它是HashMap下面有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构。
特点:有序,不可重复
package hashMap_demo;
import java.util.LinkedHashMap;
/**
* @author lx
* @date 2019/1/13 - 17:12
*/
public class LinkedHashSetDemo {
public static void main(String[] args) {
LinkedHashMap<String,String> linkedHashMap=new LinkedHashMap<>();
linkedHashMap.put("赵丽颖","冯绍峰");
linkedHashMap.put("金玟岐","金玟岐");
linkedHashMap.put("咪咕","王少");
linkedHashMap.put("卡罗","扎西");
linkedHashMap.put("赵丽颖","李易峰");
System.out.println(linkedHashMap);
/*
{赵丽颖=李易峰, 金玟岐=金玟岐, 咪咕=王少, 卡罗=扎西}
*/
}
}
计算一个字符串中每个字符出现次数
package hashMap_demo;
import java.util.HashMap;
import java.util.Scanner;
/**
* @author lx
* @date 2019/1/13 - 17:41
* 需求:
* 计算一个字符串中每个字符出现次数
* 1.从控制台获取字符串
* 2.创建一个集合,一个作为为字符,一个为次数
* 3.将字符串转化为字符,逐个遍历,判断是否是第一次出现
* 4如果是第一次出现,Integer设置为1,不是则先获取上一次的value值。再加一之后存放
*/
public class JiSuanZifuChuan {
public static void main(String [] args){
//从控制台录入字符串
Scanner scanner=new Scanner(System.in);
//获取字符串
String next = scanner.nextLine();
//创建一个集合,存储字符和次数
HashMap<Character, Integer> hashMap = new HashMap<>();
for (int i = 0; i < next.length(); i++) {
//获取字符
char c = next.charAt(i);
if (!hashMap.containsKey(c)) {
hashMap.put(c, 1);
} else {
//如果不是第一次,先取出来,然后再加一
Integer integer = hashMap.get(c);
hashMap.put(c, ++integer);
}
}
System.out.println(hashMap);
}
}
jdk9.0添加的优化
1:of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和子类实现并没有这类方法。比如 HashSet,ArrayList等;
2:返回的集合是不可变的.
public class Demo01 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("abc");
list.add("def");
list.add("ghi");
System.out.println(list); //[abc, def, ghi]
}
}
package hashMap_demo;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author lx
* @date 2019/1/13 - 18:09
*/
public class HelloJDK9 {
public static void main(String[] args) {
// of方法设置后,集合不可变
Set<String> str1 = Set.of("a", "b", "c");
// str1.add("c"); 这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合
System.out.println(str1);//[a, c, b]
Map<String, Integer> str2 = Map.of("a", 1, "b", 2);
System.out.println(str2);//{a=1, b=2}
List<String> str3 = List.of("a", "b");
System.out.println(str3);//[a, b]
}
}
模拟斗地主洗牌发牌
- 使用面向对象的方式实现斗地主洗牌发牌的操作
package douDiZhu;
import java.security.Key;
import java.util.*;
/**
* @author lx
* @date 2019/1/13 - 18:24
*
* 创建三个玩家
*
* 创建牌
* 构造牌盒
* 洗牌
* 发牌
* 看牌
*
*/
public class DouDiZhu {
public static void main(String[] args) {
//创建牌数组
String [] as={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
// 创建花色
String [] poker_color={"♠","♦","♣","♥"};
//创建牌盒
Map<Integer,String> map=new LinkedHashMap<>();
//初始化索引为1
int count=1;
for (int i = 0; i <as.length; i++) {
for (int j = 0; j <poker_color.length; j++) {
//将牌的数字和花色组合遍历
String sm=as[i]+poker_color[j];
//索引自增
map.put(count++,sm);
}
}
//添加大王小王牌面
map.put(count++,"小王🃏");
map.put(count++,"大王🃏");
//将map集合对象的键存放在set集合中
Set<Integer> set=map.keySet();
//创建ArrayList集合
ArrayList<Integer> arrayList=new ArrayList<>();
//将set集合元素全部存入ArrayList集合中
arrayList.addAll(set);
//洗牌
Collections.shuffle(arrayList);
// 发牌
// 创建三个玩家和三张底牌的索引
ArrayList<Integer> Wanjia1=new ArrayList<>();
ArrayList<Integer> wanjia2=new ArrayList<>();
ArrayList<Integer> wanjia3=new ArrayList<>();
ArrayList<Integer> dipaiNo=new ArrayList<>();
//给每个玩家发牌
for (int i = 0; i <arrayList.size() ; i++) {
Integer integer=arrayList.get(i);
if (i>=51) {
dipaiNo.add(integer);
} else{
if (i%3==0){
Wanjia1.add(integer);
} else if (i%3==1) {
wanjia2.add(integer);
}else {
wanjia3.add(integer);
}}
}
//将手中的牌按照大小排序
Collections.sort(Wanjia1);
Collections.sort(wanjia2);
Collections.sort(wanjia3);
Collections.sort(dipaiNo);
//创建玩家的牌面集合
ArrayList play1=new ArrayList();
ArrayList play2=new ArrayList();
ArrayList play3=new ArrayList();
ArrayList dipai=new ArrayList();
//遍历 根据键来获得值(牌面)
for (Integer is:Wanjia1) {
String value = map.get(is);
play1.add(value);
} for (Integer is:wanjia2) {
String value = map.get(is);
play2.add(value);
} for (Integer is:wanjia3) {
String value = map.get(is);
play3.add(value);
}for (Integer is:dipaiNo) {
String value = map.get(is);
dipai.add(value);
}
//看牌
System.out.println("哈儿"+play1);
System.out.println("逗逼" +play2);
System.out.println("傻子"+play3);
System.out.println("底牌"+dipai);
}
}
网友评论