Java集合框架(三)

时间:2021-12-28 15:24:25

 Map

Map集合:该集合存储键值对,一对一对的往里存,而且要保证键的唯一性。

Map

  |------HashTable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。

  |------HashMap:底层是哈希表数据结构,允许使用 null值和 null键,该集合是不同步的。JDK1.2,效率高。

  |------TreeMap:底层是二叉树数据结构,线程不同步,可以给map集合中的键进行排序。

和Set很像,其实,Set底层就是使用了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()

示例代码如下:

import java.util.Collection;
import java.util.HashMap;
import java.util.Map; public class MapDemo { public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>(); //添加元素
//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有的键对应的值,并put()方法返回被覆盖的值。
System.out.println("put:" + map.put("01", "zhangsan01"));//输出null
System.out.println("put:" + map.put("01", "wangwu"));
map.put("02", "zhangsan02");
map.put("03", "zhangsan03"); //System.out.println("containsKey:" + map.containsKey("022"));
//System.out.println("remove:" + map.remove("02")) ; //可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断
System.out.println("get:" + map.get("023")); map.put(null, "haha");//HashMap允许使用 null值和 null键
map.put("04", null); System.out.println("get:" + map.get("04"));
System.out.println("get:" + map.get(null)); //获取集合中所有的值
Collection<String> coll = map.values();
System.out.println(coll);
System.out.println(map); } }

 Map集合的两种取出方式

Map集合的两种取出方式:

  1、Set<K> keySet():将map所有的键存入到Set集合,因为Set集合具备迭代器,所以可以迭代方式取出所有的键,在根据get()方法,获取每一个键对应的值。

  Map集合的取出原理:将map集合转成set集合,在通过迭代器取出。

  2、Set<Map.Entry<K,V>> entrySet():将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry。

  Map.Entry,其实Entry也是一个接口,它是Map接口中的一个内部接口。代码如下:

interface Map {
public static interface Entry {
public abstract Object getKey();
public abstract Object getValue();
}
} class HashMap implements Map { class Haha implements Map.Entry {
public Object getKey() { }
public Object getValue() { }
} }

示例代码:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set; public class MapDemo1 { public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>(); map.put("01", "zhangsan01");
map.put("02", "zhangsan02");
map.put("03", "zhangsan03");
map.put("04", "zhangsan04"); //将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> me = it.next();
String key = me.getKey();
String value = me.getValue();
System.out.println(key + ":" + value);
}
/*
//先获取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);
}
*/ } }

练习1:每一个学生都有对应的归属地。学生Student,地址String。学生属性:姓名,年龄。注意:姓名和年龄相同的视为同一个学生。保证学生的唯一性。

分析:

  1. 描述学生。
  2. 定义Map容器,将学生作为键,地址作为值。存入。
  3. 获取map集合中的元素。

代码如下所示:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set; 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 void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public boolean equals(Object obj) {
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student student = (Student) obj;
return this.name.equals(student.name) &&
this.age == student.age;
} @Override
public int hashCode() {
return name.hashCode() + age * 34;
} public String toString() {
return name + ":" + age;
} @Override
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 class MapTest { public static void main(String[] args) {
HashMap<Student, String> map = new HashMap<Student, String>(); map.put(new Student("lisi1", 21), "beijing");
map.put(new Student("lisi1", 21), "tianjin");
map.put(new Student("lisi2", 22), "shanghai");
map.put(new Student("lisi3", 23), "wuhan");
map.put(new Student("lisi4", 24), "nanjing"); //第一种取出方式 keySet()
Set<Student> keySet = map.keySet(); Iterator<Student> it = keySet.iterator();
while(it.hasNext()) {
Student s = it.next();
String address = map.get(s);
System.out.println(s + "..." + address);
} //第二种取出方式 entrySet()
Set<Map.Entry<Student, String>> entrySet = map.entrySet();
Iterator<Map.Entry<Student, String>> it1 = entrySet.iterator();
while(it1.hasNext()) {
Map.Entry<Student, String> me = it1.next();
Student stu = me.getKey();
String address = me.getValue();
System.out.println(stu + "..." + address);
} } }

练习2:需求:对学生对象的姓名进行升序排序。

分析:因为数据是以键值对的形式存在的。所以要使用可以排序的Map集合。TreeMap。

代码:

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap; class Student1 implements Comparable<Student1> {
private String name;
private int age; public Student1(String name, int age) {
this.name = name;
this.age = 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 boolean equals(Object obj) {
if(!(obj instanceof Student1))
throw new ClassCastException("类型不匹配");
Student1 stu = (Student1) obj;
return this.name.equals(stu.name) &&
this.age == stu.age;
} @Override
public int hashCode() {
return name.hashCode() + age * 34;
} public String toString() {
return name + ":" + age;
} @Override
public int compareTo(Student1 s) {
int num = new Integer(this.age).compareTo(new Integer(s.age)); if(num == 0)
return this.name.compareTo(s.name); return num;
}
} class StuNameComparator implements Comparator<Student1> { @Override
public int compare(Student1 s1, Student1 s2) {
int num = s1.getName().compareTo(s2.getName()); if(num == 0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())); return num;
} }
public class MapTest1 { public static void main(String[] args) {
Map<Student1, String> tm = new TreeMap<Student1, String>(new StuNameComparator()); tm.put(new Student1("blisi3", 23), "wuhan");
tm.put(new Student1("lisi1", 21), "beijing");
tm.put(new Student1("alisi4", 24), "nanjing");
tm.put(new Student1("lisi1", 21), "tianjin");
tm.put(new Student1("lisi2", 22), "shanghai"); //System.out.println(tm); Set<Map.Entry<Student1, String>> entrySet = tm.entrySet(); Iterator<Map.Entry<Student1, String>> it = entrySet.iterator();
while(it.hasNext()) {
Map.Entry<Student1, String> me = it.next();
Student1 stu = me.getKey();
String addr = me.getValue();
System.out.println(stu + ":::" + addr);
} } }

练习3:"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。希望打印结果:a(1)c(2)...

分析:

通过结果发现,每一个字母都有对应的次数。说明字母和次数之间都有映射关系。注意:当发现有映射关系时,可以选择map集合。因为map集合中存放的就是映射关系。

问:什么时候使用map集合呢?

答:当数据之间存在着映射关系时,就要先想到map集合。

本题思路:

  1. 将字符串转换为字符数组。因为要对每一个字母进行操作。
  2. 定义一个Map集合,因为打印结果的字母有顺序,所以使用TreeMap集合。
  3. 遍历字符数组,将每一个字母作为键去查map集合。如果返回null,将该字母和1存入到map集合中。如果返回不是null,说明该字母在map集合中已经存在,并有对应次数。那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合中,覆盖掉原来键所对应的值。
  4. 将map集合中的数据变成指定的字符串返回。

代码:

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap; public class MapTest2 { public static void main(String[] args) {
String s = charCount("sdf+gz-x,cvasdf1xcvdfkk");
System.out.println(s);
} public static String charCount(String str) {
char[] chs = str.toCharArray(); TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>(); int count = 0;
for(int i = 0; i < chs.length; i++) {
if(!(chs[i] >= 'a' && chs[i] <= 'z' || chs[i] >= 'A' && chs[i] <= 'Z'))
continue;//不是字母继续循环 Integer value = tm.get(chs[i]);
if(value != null) {
count = value;
}
count++;
tm.put(chs[i], count); count = 0; /*
if(value == null) {
tm.put(chs[i], 1);
} else {
value = value + 1;
tm.put(chs[i], value);
}
*/ } //System.out.println(tm); StringBuilder sb = new StringBuilder(); Set<Map.Entry<Character, Integer>> entrySet = tm.entrySet(); Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator();
while(it.hasNext()) {
Map.Entry<Character, Integer> me = it.next();
Character ch = me.getKey();
Integer value = me.getValue();
sb.append(ch + "(" + value + ")");
} return sb.toString(); } }

 map集合扩展知识——一对多关系

一对多的关系:一个学校有多个教室,每一个教室都有名称。一个教室有多个学生。

示例代码:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List; /*
map集合扩展知识。 map集合被使用是因为具备映射关系。 "yureban" StudentM("01" "zhangsan")
"yureban" StudentM("02" "lisi") "jiuyeban" "01" "wangwu"
"jiuyeban" "02" "zhaoliu" 一对多的关系
一个学校有多个教室,每一个教室都有名称。
一个教室有多个学生。 */
class StudentM {
private String id;
private String name; public StudentM(String id, String name) {
this.id = id;
this.name = name;
} @Override
public String toString() {
return id + ":::" + name;
} }
public class MapDemo2 { public static void demo() {
HashMap<String, List<StudentM>> czbk = new HashMap<String, List<StudentM>>(); List<StudentM> yure = new ArrayList<StudentM>();
List<StudentM> jiuye = new ArrayList<StudentM>(); czbk.put("yureban", yure);
czbk.put("jiuyeban", jiuye); yure.add(new StudentM("01", "zhangsan"));
yure.add(new StudentM("04", "wangwu"));
jiuye.add(new StudentM("01", "zhouqi"));
jiuye.add(new StudentM("02", "zhaoliu")); Iterator<String> it = czbk.keySet().iterator(); while(it.hasNext()) {
String roomName = it.next();
List<StudentM> room = czbk.get(roomName);
System.out.println(roomName);
getInfos(room);
}
} public static void getInfos(List<StudentM> list) {
Iterator<StudentM> it = list.iterator();
while(it.hasNext()) {
StudentM s = it.next();
System.out.println(s);
}
} public static void main(String[] args) {
demo(); /*
HashMap<String, HashMap<String, String>> czbk = new HashMap<String, HashMap<String, String>>(); HashMap<String, String> yure = new HashMap<String, String>(); HashMap<String, String> jiuye = new HashMap<String, String>(); czbk.put("yureban", yure);
czbk.put("jiuyeban", jiuye); yure.put("01", "zhangsan");
yure.put("02", "lisi"); jiuye.put("01", "zhaoliu");
jiuye.put("02", "wangwu"); //遍历czbk集合,获取所有的教室
Iterator<String> it = czbk.keySet().iterator(); while(it.hasNext()) {
String roomName = it.next();
HashMap<String, String> room = czbk.get(roomName);
System.out.println(roomName);
getStudentMInfo(room);
} //getStudentInfo(jiuye);
*/
}
public static void getStudentInfo(HashMap<String, String> roomMap) {
Iterator<String> it = roomMap.keySet().iterator();
while(it.hasNext()) {
String id = it.next();
String name = roomMap.get(id);
System.out.println(id + ":" + name);
}
}
}