接口Map<K,V>
Map集合:该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
1,添加
put(K key, V value)
putAll(Map<? extends K, ? extends V> m)
2,删除
clear()
remove(Object key)
3,判断
containsValue(Object value)
containsKey(Object key)
isEmpty()
4,获取
get(Object key)
size()
values()
entrySet()
keySet()
Map
—Hashtable:底层是哈希数据结构,不可以存入null键null值,该集合是线程同步的。jdk1.0,效率低
—HashMap:底层是哈希表数据结构,允许使用null值和null键,该集合是不同步,jdk1.2效率高
—TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map结合中的键排序
和Set很像,其实Set底层就是使用了Map集合。
Map共性方法
public class Demo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
//添加元素,如果出现添加时相同的键,那么后添加的值会覆盖原有键值对,并put方法会返回覆盖的值
map.put("01", "zhangsan1");
map.put("02", "zhangsan2");
map.put("03", null);
map.put("04", "zhangsan4");
sop("containsKey = "+map.containsKey("01"));
sop("remove = "+map.remove("02"));
//可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断
sop("get = "+map.get("03"));
//获取map集合中所用的集合,是无序的
Collection<String> collection = map.values();
sop(collection);
}
打印结果:
containsKey = true
remove = zhangsan2
get = null
[zhangsan4, zhangsan1, null]
Map-keySet
Set keySet:将Map中所有的键存入到Set集合,因为Set具备迭代器。所以可以迭代方式取出所有的键,在根据get方法,获取每一个键对应的值。
Map 集合的取出原理:将map集合转成Set集合,在通过迭代器取出。
public class Demo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("01", "zhangsan1");
map.put("02", "zhangsan2");
map.put("03", "zhangsan3");
map.put("04", "zhangsan4");
//先获取Map集合的所有键的Set集合,keySet()
Set<String> keyset = map.keySet();
//有了Set集合,就可以获取其迭代器
Iterator<String> iterator = keyset.iterator();
while (iterator.hasNext()) {
String string = (String) iterator.next();
sop("key = "+string+", value = "+ map.get(string));
}
}
打印结果:
key = 04, value = zhangsan4
key = 01, value = zhangsan1
key = 02, value = zhangsan2
key = 03, value = zhangsan3
keyset原理图:
Map-entrySet
Set<Map.Entry<k,v> entrySet: 将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是Map.Entry
public class Demo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("01", "zhangsan1");
map.put("02", "zhangsan2");
map.put("03", "zhangsan3");
map.put("04", "zhangsan4");
Set<Map.Entry<String, String>> entries= map.entrySet();
Iterator<Map.Entry<String, String>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> mEntry = iterator.next();
String key = mEntry.getKey();
String value = mEntry.getValue();
sop("key = "+key+", value = "+ value);
}
}
打印结果:
key = 04, value = zhangsan4
key = 01, value = zhangsan1
key = 02, value = zhangsan2
key = 03, value = zhangsan3
entrySet图例
Map.Entry 其实Entry也是一个接口,它是Map接口中的一个内部接口
Map练习
每一个学生都有对应的归属地,学生Student,地址String。
学生属性:姓名,年龄
注意:姓名和年龄相同的视为同一个学生,保证学生的唯一性。
1,描述学生
2,定义一个map容器,将学生作为键,地址作为值 存入
3,获取map集合的元素。
class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
* 一想到Hash集合就要想到HashCode和equals
*/
@Override
public int hashCode() {
return name.hashCode()+age*34;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Student)) {
throw new ClassCastException("类型不匹配");
}
Student other = (Student) obj;
return this.name.equals(other.name) && this.age == other.age;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
//数据有可能会存到二叉树中,所以还是要覆写上排序的方法
@Override
public int compareTo(Student o) {
int num = new Integer(this.age).compareTo(new Integer(o.age));
if (num == 0) {
return this.name.compareTo(o.name);
}
return num;
}
}
public class Demo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
HashMap<Student, String> map = new HashMap<Student, String>();
map.put(new Student("zhangsan", 18), "beijing");
map.put(new Student("lisi", 33), "xian");
map.put(new Student("wangwu", 25), "shenzhen");
map.put(new Student("xiaoming", 23), "hebei");
map.put(new Student("xiaoming", 23), "shanghai");//会覆盖上面的值
//第一中方式取出
Set<Student> set = map.keySet();
Iterator<Student> iterator = set.iterator();
while (iterator.hasNext()) {
Student student = iterator.next();
String value = map.get(student);
sop("student:"+student + " , value:"+ value);
}
//第二种取出方式
Set<Map.Entry<Student, String>> entries= map.entrySet();
Iterator<Map.Entry<Student, String>> iterator1 = entries.iterator();
while (iterator1.hasNext()) {
Map.Entry<Student, String> mEntry = iterator1.next();
Student key = mEntry.getKey();
String value = mEntry.getValue();
sop("key = "+key.toString()+", value = "+ value);
}
}
打印结果:
student:Student [name=wangwu, age=25] , value:shenzhen
student:Student [name=zhangsan, age=18] , value:beijing
student:Student [name=xiaoming, age=23] , value:shanghai
student:Student [name=lisi, age=33] , value:xian
key = Student [name=wangwu, age=25], value = shenzhen
key = Student [name=zhangsan, age=18], value = beijing
key = Student [name=xiaoming, age=23], value = shanghai
key = Student [name=lisi, age=33], value = xian
TreeMap练习
需求:按照学生的姓名进行排序。
因为数据是以键值对形式存在的,所以要使用可以排序的map集合,TreeMap.
class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
* 一想到Hash集合就要想到HashCode和equals
*/
@Override
public int hashCode() {
return name.hashCode()+age*34;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Student)) {
throw new ClassCastException("类型不匹配");
}
Student other = (Student) obj;
return this.name.equals(other.name) && this.age == other.age;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
//数据有可能会存到二叉树中,所以还是要覆写上排序的方法
//按照年龄排序
@Override
public int compareTo(Student o) {
int num = new Integer(this.age).compareTo(new Integer(o.age));
if (num == 0) {
return this.name.compareTo(o.name);
}
return num;
}
}
class StuComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
//按照年龄排序
int num = o1.getName().compareTo(o2.getName());
if (num == 0) {
return new Integer(o1.getAge()).compareTo(o2.getAge());
}
return num;
}
}
public class Demo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
TreeMap<Student, String> treeMap = new TreeMap<Student, String>(new StuComparator());
treeMap.put(new Student("zhangsan", 18), "beijing");
treeMap.put(new Student("lisi", 33), "xian");
treeMap.put(new Student("wangwu", 25), "shenzhen");
treeMap.put(new Student("xiaoming", 23), "hebei");
treeMap.put(new Student("xiaoming", 23), "shanghai");
Set<Map.Entry<Student, String>> entries= treeMap.entrySet();
Iterator<Map.Entry<Student, String>> iterator1 = entries.iterator();
while (iterator1.hasNext()) {
Map.Entry<Student, String> mEntry = iterator1.next();
Student key = mEntry.getKey();
String value = mEntry.getValue();
sop("key = "+key.toString()+", value = "+ value);
}
}
打印结果:
key = Student [name=lisi, age=33], value = xian
key = Student [name=wangwu, age=25], value = shenzhen
key = Student [name=xiaoming, age=23], value = shanghai
key = Student [name=zhangsan, age=18], value = beijing
TreeMap练习2
"shnsjljsjkdjndhskdn"获取该字符串中字母出现的次数。
希望打印结果:a(1)c(2)…
思路:
1,将字符串转换成字符数组,因为要对每一个字母进行操作
2,定义一个Map集合,因为打印结果的字母有顺序,所以使用treemap集合
3,遍历字符数组。将每一个字母作为键去查Map集合,如果返回为null,将将该字母和1存入到Map集合中,如果返回不是null,说明该字母在Map集合已经存在并有对应次数,那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到Map集合中,覆盖原来键对应的值
4,将Map集合中的数据变成指定的字符串形式返回。
public class Demo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
String str = "sh+nsjlj1sjkdjn-dhskdn";
int count = 0;
char [] cs = str.toCharArray();
TreeMap<Character,Integer> treeMap = new TreeMap<Character,Integer>();
for (int i = 0; i < cs.length; i++) {
//如果非字母,继续循环
if(!(cs[i] >= 'a' && cs[i] <= 'z' || cs[i] >= 'A' && cs[i] <= 'Z'))
continue;
Integer value = treeMap.get(cs[i]);
if(value != null)
count = value;
count++;
treeMap.put(cs[i], count);
count =0;
/*或者这样判断,也可以的
* if (value == null) {
treeMap.put(cs[i], 1);
}else {
treeMap.put(cs[i], value+1);
}*/
}
StringBuffer buffer = new StringBuffer();
Set<Map.Entry<Character,Integer>> set = treeMap.entrySet();
Iterator<Map.Entry<Character,Integer>> iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry<Character,Integer> entry = iterator.next();
buffer.append(entry.getKey() + "("+entry.getValue()+")");
sop(buffer.toString());
}
}
打印结果:
d(3)h(2)j(4)k(2)l(1)n(3)s(4)
Map扩展
map集合被使用是因为具备映射关系,一对多映射
一个学校有多个教室,一个教室里有多个学生
class Student{
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
public class Demo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
HashMap<String, List<Student>> school = new HashMap<String, List<Student>>();
List<Student> aClass = new ArrayList<Student>();
List<Student> bClass = new ArrayList<Student>();
school.put("A class", aClass);
school.put("B class", bClass);
aClass.add(new Student("01", "zhangdan"));
aClass.add(new Student("02", "wangwu"));
aClass.add(new Student("01", "lisi"));
aClass.add(new Student("02", "xiaoming"));
//遍历学校,获取班级
Set<String> set = school.keySet();
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String classStr = iterator.next();
getStudentInfor(school.get(classStr));
}
}
public static void getStudentInfor(List<Student> list){
Iterator<Student> iterator = list.iterator();
while (iterator.hasNext()) {
Student student = (Student) iterator.next();
sop(student.getId() + " ,name = "+student.getName());
}
}
打印结果:
01 ,name = zhangdan
02 ,name = wangwu
01 ,name = lisi
02 ,name = xiaoming