集合框架Map介绍
之前我们提到过,集合框架这一定义包含了List,Set 和Map这些定义,(如下图),但List和Set的共性Collection这是Map所没有的。
面试题:(List集合,Set集合,Map集合是否继承于同一个接口?)看图就知道,肯定不是。
由上面这张图,我们也应该可以猜到Map和Set是不是差不多呢?确实如此。
其中,Map包含了HashMap,TreeMap,HashTable。在这里,HashTable我们可以一带而过,不做过多的研究,Ta就相当于List中的Vector,(退休的老干部).
Set有的特点 Map都有 ,比如HashSet能判重,HashMap也可以。
可以这么说,Map集合的底层就是Set集合。
而TreeMap就相当于TreeSet了,可以排序等。
在Map集合中,存放的都是一组组映射关系。
是通过key=value来体现。(eg:一个学生对应一个城市)
map集合中,key不能重复~!
小结:
Map
Hashtable:底层是哈希表数据结构,不可以存入null键null值,该集合石线程同步的,jdk1.0,效率低
HashMap:底层是哈希表数据结构,允许使用null值和null键,该集合是不同步的。将Hashtable替代;jdk1.2,效率高
TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map集合中的键进行排序
当然Map集合也有很多方法
1、增加
put(K key, V value)
putAll(Map<? extends K,? extends V> m)
2、删除
clear()
remove(Object key)
3、判断
containsKey(Object key)
containsValue(Object value)
isEmpty()
4、获取
get(Object key)
size()
values()
entrySet()
keySet()
都是通过键去操作
本篇中,我们也将着重讲几个方法
a:put
b:entrySet
c:keySet
根据需求,当我们需要改掉用户表某一数据的时候,(比如身份证号码等敏感话题)
来展示在前台,以至前台不能看见,(很好的例子,快递上电话号码的***)这时候,我们就需要进一步探讨了,如下图,简单的替换(将value值变为*)
map.put("java04", 3);
map.put("java04","*");
输出结果为:java04=*
a:put(两点):
1.添加集合元素的同时,它可以编辑原有的元素
如果说集合中没有key对应的值,那么就往集合中添加元素
如果说集合中对应的key有value值,则代表替换原有的值
但问题来了,我们用替换了,但当我们需要用到的时候,怎么办呢?*
如下代表;
Object put = map.put("java04", "*");
System.out.println(put);
实际效果为:3
第二点
2.返回替换前对应的value值
我们得知道,Map集合是没有迭代器方法的。
因此是通过entrySet和keySet来取元素的。
b:entrySet
本身是属于map集合的类,相当于迭代器
这是他的内部代码
怎么去取?:根据映射关系取,(一组一组分开取,意思是key和value都知道)
如下图,
c:keySet
通过key取(好比只知道一部分名单)
相比较entrySet性能要好一点
好了,Map许多方法,及其包含意义差不多讲完了,接下来咱们讲讲Map应用吧
集合框架Map应用
(用map集合完成需求)
Demo1
1、将学生作为键,地址作为值进行存储,名字年龄相同则被认定为一个人,最后输出
2、最后按年龄进行排序
3、需求改变、按姓名进行排序
思路:
a.建立一个Student类,实例化作为key添加到map中
class Student{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
}
b.对学生进行判重
public int hashCode() {
return this.getName().hashCode() + this.getAge()*39;
}
@Override
public boolean equals(Object obj) {
Student stu = (Student)obj;
return this.getAge() == stu.getAge() &&this.getName().equals(stu.getName());
}
@Override
public int compareTo(Student o) {
int num = this.getAge()-o.getAge();
if(num==0) {
return this.getName().compareTo(o.getName());
}
return num;
}
}
class StuComp implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
int num = o1.getName().compareTo(o2.getName());
if(num==0) {
return o1.getAge()-o2.getAge();
}
return num;
}
}
如图:
Demo2
统计字符串中字符出现次数
思路:统计,排序
统计功能:
map集合中的泛型要使用包装类,或者引用数据类型
1.将字符串转为字符数组,将这个字符串中的字符当做map集合中的key,将出现的次数作为value值
2.当字符第一次出现的时候,那么用它在集合中进行寻找,返回值必然为null,之后,该字符对应的值改为1
3.如果说该字符不是第一次出现,该字符对应的值就应该不为null,应该+1private static String cishu(String str) { char[] charArray = str.toCharArray(); Map<Character, Integer> map = new TreeMap<>(); for (char c : charArray) { Integer value = map.get(c); if(value==null) { map.put(c, 1); } else { map.put(c, ++value); } } //StringBuffer跟String StringBuffer sb = new StringBuffer(); for(Map.Entry<Character, Integer> entry:map.entrySet()) { sb.append(entry.getKey() + "(" +entry.getValue()+")"); } return sb.toString(); } }
效果如下:
,按次数排序:
sb.append(entry.getValue() + "(" +entry.getKey()+")");