此博客意在详细介绍一下java中的map
一、map基本方法
在java.util包中有一个map接口,map<K,V>,他使用了两个泛型,是一个单独的接口,不属于collection,属于集合,最重要的是,他存放的东西,是键值对,前面的K表示键的类型,后面的V表示值的类型
添加:
V put(K key,V value)
void putAll(Map <? extengds V> m)
删除:
V remove(object key)
void clear()
获取:
V get(Object key)
Set<K> keySet()
Set<Map.Entry<K,V>> entrySet()
int size()
Collection<V> values()
判断:
boolean isEmpty()
boolean containKey(Object key)
boolean containsValue(Object value)
在map下需要掌握的有两种:
HashMap:底层使用的数据结构是哈希表,线程不安全的
TreeMap:底层使用的数据结构是二叉树,线程不安全的
import java.util.*;
class Demo{
public static void main(String[] args){
//键是不能重复的,如果键重复了,那么后添加的会覆盖之前添加的
Map<String,String> map = new HashMap<>();
//添加键值对
//put方法有返回值,返回的是上一次添加的相同键的值
//System.out.println(map.put("001","dongdong"));//返回null
//System.out.println(map.put("001","嘻嘻"));//返回dongdong
map.put("001","dongdong");
map.put("002","xixi");
map.put("003","nannan");
map.remove("001");//根据键删除一对
System.out.println(map);
String value = map.get("002");//根据键获取值
System.out.println(value);
Collection<String> values = map.values();//得到所有值的集合,注意是值
Iterator<String> ite = values.iterator();
while(ite.hasNext()){
System.out.println(ite.next());
}
boolean b1 = map.containsKey("003");//判断是否包含某个键
boolean b2 = map.containsValue("xixi");//判断是否包含某个值
System.out.println(b1 + "," + b2);
}
}
二、遍历Map集合
遍历Map集合的方式:
Set<K> keySet():得到所有键的集合存储到一个Set中,并返回该Set集合,因为Set有迭代器所以使用迭代器迭代,每次迭代出一个键,再根据键获取值
每一个键值对之间存在一个映射关系,映射关系是一种数据类型,每一个键值对对应一个映射关系类型的值↓
Set<Map.Entry<K,V>> entrySet():得到啊每个键值对对应的映射关系类型的值,存到Set集合中,并返回该集合,因为Set有迭代器,每次迭代出来的是一个映射关系类型的值,从这个映射关系类型的值中既可以得到键,也可以得到值
Entry是定义在Map中的一个静态接口,有了集合,也有了集合中的键值对,才会存在映射关系所以映射关系时对集合内部事物的描述,所以定义在 Map内部
import java.util.*;
class Demo
{
public static void main(String[] args){
Map<String,String> map = new HashMap<>();
map.put("001","dongdong");
map.put("002","xixi");
map.put("003","nannan");
//entrySet返回一个Set集合,集合中存放的是每个键值对对应的映射关系类型的值
Set<Map.Entry<String,String>> entry = map.entrySet();
Iterator<Map.Entry<String,String>> ite = entry.iterator();
while(ite.hasNext()){
Map.Entry<String,String> en = ite.next();
String key = en.getKey();
String value = en.getValue();
System.out.println(key+"="+value);
}
/*
//KeySet方法返回一个键组成的Set集合
Set<String> keys = map.keySet();
Iterator<String> ite = keys.iterator();
while(ite.hasNext()){
String key = ite.next();
String value = map.get(key);
System.out.println(key+"="+value);
}
*/
}
}
三、HashMap的基本使用
什么时候使用Map?
当存在映射关系
比如:每个学生对应一个住址
import java.util.*;
class Student{
private String name;
private int age;
public Student(){}
public Student(String name,int age){
this.name = name;
this.age = age;
}
//为了实现姓名年龄相同才是同一个键,需要重写以下两种方法
//重写int hashCode()方法,hashCode()返回值相同了,会去调用下面的equals方法
public int hashCode(){
//乘以36是为了减小相同的概率,可以使乘以随机值
return name.hashCode()+age*36;
}
//重写boolean equals(Object obj)方法
public boolean equals(Object obj){
if(!(obj instanceof Student))
throw new ClassCastException("类型转换异常");
//强制转换后才能用
Student stu = (Student)obj;
//姓名年龄相同返回true
return this.name.equals(stu.name) && this.age==stu.age;
}
//重写toString方法
public String toString(){
return name+","+age;
}
}
class Demo{
public static void main(String[] args){
HashMap<Student,String> map = new HashMap<>();
//如何保证键不重复:和hashSet一样的 先依据int hashCode() 再调用boolean equals(Object obj)比较内存地址
//键是Student类型,值是String类型
map.put(new Student("zhangbo",23),"henan");
map.put(new Student("liuzhenqi",20),"haijiao");
map.put(new Student("dongdong",22),"shanxi");
//重写了hashCode()和equals()方法后,beijing会覆盖haijiao
map.put(new Student("liuzhenqi",20),"beijing");
Iterator<Student> ite = map.keySet().iterator();
while(ite.hasNext()){
Student stu = ite.next();
String value = map.get(stu);
System.out.println(stu+"="+value);
}
}
}
四、TreeMap的基本使用
因为TreeMap底层结构用的是二叉树,所以他可以进行自动排序,根据键来进行排序
import java.util.*;
/*
//第二种方法实现排序:自己定义一种排序方式
class ComByAge implements Comparator<Student>{
public int compare(Student s1,Student s2){
//先看年龄是否相同,年龄不同再用compareTo方法看姓名是否相同
int num = s1.getAge() - s2.getAge();
return num==0?s1.getName().compareTo(s2.getName()):num;
}
}*/
//第一种方法实现排序,让Student实现Comparable接口,内部实现compareTo方法↓
class Student implements Comparable<Student>{
private String name;
private int age;
public Student(){}
public Student(String name,int age){
this.name = name;
this.age = age;
}
//实现compareTo方法
public int compareTo(Student stu){
int num = this.name.compareTo(stu.name);
return num==0?this.age-stu.age:num;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public String toString(){
return name+","+age;
}
}
class Demo{
public static void main(String[] args){
ComByAge com = new ComByAge();
//第一种排序:
TreeMap<Student,String> map = new TreeMap<>();
//第二种排序:
//有了自定义的比较方式后,Student中定义的比较方式,也就是第一种方法,就失效了,系统会调用自定义的比较方式
//TreeMap<Student,String> map = new TreeMap<>(com);
//根据什么来排序的?根据键排序 原理和TreeSet一样的,两种方法
//一、键所属的类实现Comparable接口,内部实现compareTo方法
//二、或者自己定义一种排序方式
map.put(new Student("zhangbo",23),"henan");
map.put(new Student("liuzhenqi",21),"haijiao");
map.put(new Student("dongdong",22),"shanxi");
//使用上面介绍的entrySet方法遍历
Set<Map.Entry<Student,String>> en = map.entrySet();
Iterator<Map.Entry<Student,String>> ite = en.iterator();
while(ite.hasNext()){
Map.Entry<Student,String> entry = ite.next();
Student stu = entry.getKey();
String value = entry.getValue();
System.out.println(stu+"="+value);
}
}
}
注意:
HashMap:保证键不能重复的原理和HashSet是一样的
TreeMap:根据键来排序,排序的原理和TreeSet是一样的