目录
Map集合
该集合存储键值对,一对一对往里存,而且保证键的唯一性
和set很像,Set底层就是使用了Map集合
子类对象
Hashtable:底层是哈希表数据结构,不可以存入null键,null值,该集合是线程同步的,jdk1.0,效率低
HashMap:底层是哈希表数据结构,允许使用null值和null键,该集合是不同步的,jdk1.2,效率高
TreeMap:底层是二叉树数据结构,线程不同步,可以用于给map集合中的键进行排序
Map集合的两种取出方式:
(Map取出原理:将map集合转成set集合,在通过迭代器取出)
1.keySet:将map中所有的键存入到Set集合,因为set具备迭代器,所有可以迭代方式取出所有的键,在根据get方法,获取每一个键对应的值---返回值类型:Set<k>
class KeySetDemo
{
public static void main(Stirng[] args)
{
Map<string,string> map =new HashMap<String,String>();
map.put("01","lisi1");
map.put("02","lisi2");
map.put("03","lisi3");
map.put("04","lisi4");
//先获取map集合的所有键的Set集合,keySet()
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)
}
}
}
//输出结果:
key:04,value:lisi4
key:01,value:lisi1
key:03,value:lisi3
key:02,value:lisi2
输出结果是无序的,因为数据结构是哈希表
2.entrySet:
将map集合中的映射关系存入到了set集合中,而这个关系的数据类型是:Map.Entry---返回值:Set<Map.Entry<k,v>>
Map.Entry是一个接口,其实Entry也是一个接口,它是Map接口中的一个内部接口
class EntryDemo
{
public static void main(Stirng[] args)
{
Map<string,string> map =new HashMap<String,String>();
map.put("01","lisi1");
map.put("02","lisi2");
map.put("03","lisi3");
map.put("04","lisi4");
//将Map集合中的映射关系取出,存入到Set集合中
Set<Map.Entry<String,String>> entrySet = map.entrySet();
Iterator<Map.Entry<String,String>> it =entrySet.iterator();
while(it.hasNext())
{
Map.Entry<String,String> key =it.next();
String value =map.getValue();
System.out.println("key:"+key+",value:"+value)
}
}
}
//输出结果:
key:04,value:lisi4
key:01,value:lisi1
key:03,value:lisi3
key:02,value:lisi2
输出结果是无序的,因为数据结构是哈希表
应用实例:从存到取
/*
需求:
1.描述学生
2.定义map容器,将学生作为键,地址作为值,存入
3.获取map集合中的元素
*/
class Student
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
//排序,这个考虑到不知道用什么来存,如果用到二叉树来存就要使学生有一个自然顺序(如果产生N多个对象,最好产生一个自然顺序)
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;
}
//有可能存在哈希表中,需要判断唯一性
public int hashCode()
{
return name.hashCode()+age*34;
}
//有可能存在哈希表中,需要判断唯一性
public boolean equlas(Object obj)
{
if(!obj instaceof Student)
throw new ClassCastExcetion("类型不匹配");
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 MapTest
{
public static void main(String[] args)
{
HashMap<Student,String>hm =new HashMap<Student,String>();
hm.put(new Student("lisi1",21),"beijing");
hm.put(new Student("lisi2",22),"shanghai");
hm.put(new Student("lisi3",23),"hangzhou");
//第一种取出方式 keySet
Set<Student> keySet=hm.KeySet();
Iterator<Student> it= keySet.iterator();
while(it.hasNext())
{
Student stu=it.next();
String addr =hm.get(stu);
System.out.println(stu+"..."+addr);
}
//第二种取出方式:entrySet
Set<Map.Entry<Student,String>> entrySet=hm.entrySet();
Iterator<Map.Entry<Student,String>> iter= entrySet.iterator();
while(it.hasNext())
{
Map.Entry<Student,String> me=iter.next();
Student stu = me.getKey();
String addr=me.getValue();
System.out.println(stu+"......"+addr);
}
}
}
输出结果:
lisi2:22...shanghai
lisi3:23...hangzhou
lisi1:21...beijing
lisi3:23......hangzhou
lisi2:22......shanghai
lisi1:21......beijing
(PS:添加元素时:如果出现添加时,相同的键,那么后添加的值会覆盖原有键对相应的值,并put方法会返回被覆盖的值)
TreeMap
将存入到map中的数据进行排序,TreeMap有默认的排序,为自然排序,我们也可以自定义排序
class Studnet implements Comparable<Student>
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
//排序,这个考虑到不知道用什么来存,如果用到二叉树来存就要使学生有一个自然顺序(如果产生N多个对象,最好产生一个自然顺序)
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;
}
//有可能存在哈希表中,需要判断唯一性
public int hashCode()
{
return name.hashCode()+age*34;
}
//有可能存在哈希表中,需要判断唯一性
public boolean equlas(Object obj)
{
if(!obj instaceof Student)
throw new ClassCastExcetion("类型不匹配");
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;
}
}
import java.util.*;
class StuNameComparator 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(s.getAge())));
return num;
}
}
class MapTest
{
public static void main(String[] args)
{
//StuNameComparator比较器
TreeMap<Student,String> tm =new TreeMap<Student,String>(new StuNameComparator)
tm.put(new Student("blisi3",23),"nanjing");
tm.put(new Student("lisi1",21),"beijing");
tm.put(new Student("alisi4",24),"wuhan");
tm.put(new Student("lisi2",22),"shanghai");
Set<Map.Entry<Student,String>> entrySet =tm.entrySet();
Iterator<Map.Entry<Student,String>> it =entrySet.iterator();
while(it.hasNext())
{
Map.Entry<Student,String> me= it.next();
Student stu =me.getKey();
String addr =mew.getVlaue();;
System.out.println(stu+":::"+addr);
}
}
}
输出结果:
alisi4:24:::wuhan
blisi3:23:::nanjing
lisi1:21:::beijing
lisi2:22:::shanghai
Comparable 和 Comparator 的对比
1、Comparable 更像是自然排序
2、Comparator 更像是定制排序
同时存在时采用 Comparator(定制排序)的规则进行比较。
对于一些普通的数据类型(比如 String, Integer, Double…),它们默认实现了Comparable 接口,实现了 compareTo 方法,我们可以直接使用。
而对于一些自定义类,它们可能在不同情况下需要实现不同的比较策略,我们可以新创建 Comparator 接口,然后使用特定的 Comparator 实现进行比较。