一、Map集合特点:存储的是键值对,键必须唯一
V put(K key, V value)
将指定的值与此映射中的指定键关联(可选操作)。
当键相同时,用新值替换旧值,并返回原来的值
void putAll(Map<? extends K,? extends V> m)
从指定映射中将所有映射关系复制到此映射中(可选操作)。
2、删
void clear()
从此映射中移除所有映射关系(可选操作)。
V remove(Object key)
如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
3、判断
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolean equals(Object o)
比较指定的对象与此映射是否相等。
boolean isEmpty()
如果此映射未包含键-值映射关系,则返回 true。
4、获取
V get(Object key)
返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
int size()
返回此映射中的键-值映射关系数。
Collection<V> values()
返回此映射中包含的值的 Collection 视图。
重点:
Set<Map.Entry<K,V>> entrySet()
返回此映射中包含的映射关系的 Set 视图。
Set<K> keySet()
返回此映射中包含的键的 Set 视图。
|--Hashtable:底层是哈希表,必须实现 hashCode 方法和 equals 方法。jdk1.0 效率低
不能存储null值和键,线程同步
|--HashMap:底层是哈希表,允许使用 null 值和 null 键。不同步jdk1.2 效率高
|--TreeMap :底层是二叉树,线程不同步,键排序
和set很像,其他set底层就是使用了Map集合
常用方法:
1、增V put(K key, V value)
将指定的值与此映射中的指定键关联(可选操作)。
当键相同时,用新值替换旧值,并返回原来的值
void putAll(Map<? extends K,? extends V> m)
从指定映射中将所有映射关系复制到此映射中(可选操作)。
2、删
void clear()
从此映射中移除所有映射关系(可选操作)。
V remove(Object key)
如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
3、判断
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolean equals(Object o)
比较指定的对象与此映射是否相等。
boolean isEmpty()
如果此映射未包含键-值映射关系,则返回 true。
4、获取
V get(Object key)
返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
int size()
返回此映射中的键-值映射关系数。
Collection<V> values()
返回此映射中包含的值的 Collection 视图。
重点:
Set<Map.Entry<K,V>> entrySet()
返回此映射中包含的映射关系的 Set 视图。
Set<K> keySet()
返回此映射中包含的键的 Set 视图。
二、体系结构
Map|--Hashtable:底层是哈希表,必须实现 hashCode 方法和 equals 方法。jdk1.0 效率低
不能存储null值和键,线程同步
|--HashMap:底层是哈希表,允许使用 null 值和 null 键。不同步jdk1.2 效率高
|--TreeMap :底层是二叉树,线程不同步,键排序
和set很像,其他set底层就是使用了Map集合
三、元素存取
import java.util.*;
/*
Map实例
*/
class MapTest {
public static void main(String[] args) {
HashMap<String, String> h = new HashMap<String, String>();
//添加数据
h.put("01","lisi1");
h.put("03","lisi3");
h.put("04","lisi2");
//获取
out(h.get("03"));
}
//输出
public static void out(Object obj) {
System.out.println(obj);
}
}四、Map集合和取出方式
Map集合取出原理:将Map集合转成Set集合,通过迭代器。在调用put()
1、keySet();将Map中所有的键存入Set集合,在根据get方法
获取每一个键对应的值
import java.util.*;
/*
Map实例
用keySet()取出所有的键和值
*/
class MapTest1 {
public static void main(String[] args) {
HashMap<String, String> h = new HashMap<String, String>();
//添加数据
h.put("01","lisi1");
h.put("03","lisi3");
h.put("04","lisi2");
//生产set集合
Set<String> set = h.keySet();
//迭代器
Iterator<String> it = set.iterator();
//遍历元素
while(it.hasNext()) {
String key = it.next();
String value = h.get(key);
out("key->" + key + " value->" + value);
}
}
//输出
public static void out(Object obj) {
System.out.println(obj);
}
}
2、用entrySet()取元素
import java.util.*;
/*
Map实例
用entrySet()取出所有的键和值
*/
class MapTest2 {
public static void main(String[] args) {
HashMap<String, String> h = new HashMap<String, String>();
//添加数据
h.put("01","lisi1");
h.put("03","lisi3");
h.put("04","lisi2");
//生产set集合
Set<Map.Entry<String, String>> set = h.entrySet();
//迭代器
Iterator<Map.Entry<String, String>> it = set.iterator();
//遍历元素
while(it.hasNext()) {
Map.Entry<String, String> m = it.next();
String key = m.getKey();
String value = m.getValue();
out(key + ":" + value);
}
}
//输出
public static void out(Object obj) {
System.out.println(obj);
}
}
Map.Entry:内部实现
(1)在Map接口中定义了一个静态Entry接口
interface Map {
public static interface Entry {
//一些方法
}
}
(2)Map类实现细节
class HashMap implements Map {
class Ha implements Map.Entry {
//复写方法
}
} 五、综合实例
import java.util.*;
/*
综合练习:将学生对象存储到HashMap中的键,值为住址
姓名和年龄相同视为同一人
思路:
1、描述学生
实现Comparable接口,覆盖compareTo() //是对象具有自然顺序
重写equals(),HashCode() //存储到hash结构的容器中
和toSting()
2、将学生存储到HashMap容器中
3、分别用keySet()和entrySet()对元素遍历
*/
//学生
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;
}
//复写equlas
public boolean equlas(Object obj) {
if (obj instanceof Student)
throw new ClassCastException("对象类型错误!");
Student s = (Student)obj;
return this.name.equals(s.name) && this.age == s.age;
}
//复写hashCode
public int hashCode() {
return this.name.hashCode() + age * 7;
}
//复写compareTo
public int compareTo(Student s) {
int num = this.name.compareTo(s.name); //先按照姓名排序,升序
if (num == 0) { //如果姓名相同,按年龄,升序
return new Integer(this.age).compareTo(new Integer(s.age));
}
return num;
}
//复写toString
public String toString() {
return name + "..." + age;
}
}
//main
class HashMapTest {
public static void main(String[] args) {
//创建容器
HashMap<Student, String> hs = new HashMap<Student, String>();
//添加数据
hs.put(new Student("lisi1",14), "四川");
hs.put(new Student("lisi4",19), "深圳");
hs.put(new Student("lisi3",29), "北京");
hs.put(new Student("lisi5",11), "上海");
//第一种方法keySet()取数据
Set<Student> set = hs.keySet();
//迭代器
Iterator<Student> it = set.iterator();
//循环取出数据
while(it.hasNext()) {
Student key = it.next();
String addr = hs.get(key);
out("name:" + key.getName() + " age:" + key.getAge() + " 地址:" + addr);
}
out("");
//第二种方法entrySet()
//获取键值映射的Set集合
Set<Map.Entry<Student, String>> s1 = hs.entrySet();
//迭代器
Iterator<Map.Entry<Student, String>> iter = s1.iterator();
//循环取元素
while(iter.hasNext()) {
Map.Entry<Student, String> mp = iter.next();
Student stu = mp.getKey();
String addrs = mp.getValue();
out("name:" + stu.getName() + " age:" + stu.getAge() + " addr:" + addrs);
}
}
//输出
public static void out(Object obj) {
System.out.println(obj);
}
}六、综合实例改进
import java.util.*;
/*
实现对学生对象的排序用TreeSet容器(默认是姓名排序)
现在要求用年龄升序
注意: 学生对象同上
*/
//main
class HashMapTest1 {
public static void main(String[] args) {
//创建容器
TreeMap<Student, String> hs = new TreeMap<Student, String>(new StudentNameComparator());
//添加数据
hs.put(new Student("lisi1",14), "四川");
hs.put(new Student("lisi4",19), "深圳");
hs.put(new Student("lisi3",29), "北京");
hs.put(new Student("lisi5",11), "上海");
//获取键值映射的Set集合
Set<Map.Entry<Student, String>> s1 = hs.entrySet();
//迭代器
Iterator<Map.Entry<Student, String>> iter = s1.iterator();
//循环取元素
while(iter.hasNext()) {
Map.Entry<Student, String> mp = iter.next();
Student stu = mp.getKey();
String addrs = mp.getValue();
out("name:" + stu.getName() + " age:" + stu.getAge() + " addr:" + addrs);
}
}
//输出
public static void out(Object obj) {
System.out.println(obj);
}
}
//学生比较器
class StudentNameComparator implements Comparator<Student> {
public int compare(Student s1, Student s2) {
int num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
if (num == 0)
return s1.getName().compareTo(s2.getName());
return num;
}
}七、实例2
什么时候使用map集合:当数据直接出现映射关系时
import java.util.*;
/*
练习:统计字符串中字母出现的次数
输出如;a(13)b(3)c(9)...
思路:
1、定义一个TreeMap,因为数据之间有映射关系,而且是自然排序
2、将字符串转成数组toCharArray()
3、遍历字符数组,取出一个字符,去TreeMap中查询get()
如果返回值为null说明,该字符以前没有出现,就将该字母和1
作为键值对存入。
否则,将出来的值加1,该字母和该值存入
4、定义字符串缓冲区,拼接字符串(StringBuilder)
*/
class TreeMapCount {
public static void main(String[] args) {
String str = "anglakjngdpang";
out(countChar(str));
}
//输出方法
public static void out(Object obj) {
System.out.println(obj);
}
//统计字母出现次数方法
public static String countChar(String str) {
//将字符串转成数组
char[] chs = str.toCharArray();
TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
//遍历字符串
Integer count = 0;
for (int i=0;i<chs.length;i++) {
/*
Character ch = chs[i];
Integer value = tm.get(ch);
if (value == null) {
tm.put(ch, 1);
} else {
value++;
tm.put(ch, value);
}
*/
Character ch = chs[i];
Integer value = tm.get(ch);
if (value != null)
count = value;
count++;
tm.put(ch, count);
count = 0;
}
//拼接字符串
StringBuilder sb = new StringBuilder();
//获取键值映射集合Set
Set<Map.Entry<Character, Integer>> set = tm.entrySet();
//迭代器
Iterator<Map.Entry<Character, Integer>> it = set.iterator();
//循环取值
while(it.hasNext()) {
Map.Entry<Character, Integer> me = it.next();
Character c = me.getKey();
Integer value = me.getValue();
sb.append(c + "(" + value + ")");
}
return sb.toString();
}
}
八、Map扩展知识
import java.util.*;
/*
练习:
需求:对如下数据进行存储
有一个学校,一个学校有很多班级,一个班级有很多学生,
每个学生信息,姓名,学号
分析:
1、多对多关系,一个学校有很多个班级,班级有名称
2、一个班级有很多学生,每个学生属于一个班级
步骤:
1、描述学生
2、定义一个学生HashMap
3、定义多个班级,
4、向每个班级中添加学生
*/
//学生类
class Student {
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return id + "..." + name;
}
}
//main
class StorageTest {
public static void main(String[] args) {
method2();
}
//第一种方式,不将学校封装成对象,就要用HashMap,因为,
//学号和姓名要一一对应
public static void method1() {
//创建学校
HashMap<String, HashMap<String, String>> school = new HashMap<String, HashMap<String, String>>();
//创建班级
HashMap<String, String> ruanjianban = new HashMap<String, String>();
HashMap<String, String> yishuban = new HashMap<String, String>();
HashMap<String, String> dongmanban = new HashMap<String, String>();
//将班级与学校关联
school.put("软件班", ruanjianban);
school.put("艺术班", yishuban);
school.put("动漫班", dongmanban);
//向每个班级添加学生
ruanjianban.put("01", "zhangsan");
ruanjianban.put("02", "lisi");
ruanjianban.put("04", "wanger");
yishuban.put("02", "zhangsan1");
yishuban.put("01", "zhaoliu");
dongmanban.put("05", "wangsan");
//打印这个学校的学生信息
outInfo(school);
}
//打印学生信息
public static void outInfo(HashMap<String, HashMap<String, String>> s) { //传一个学校
//先循环出班级的名称
Iterator<String> it = s.keySet().iterator();
while (it.hasNext()) {
String room = it.next();
out(room);
//在由班级名称查找对于的学生
HashMap<String, String> mm = s.get(room); //班级对象
Iterator<String> it1 = mm.keySet().iterator();
while(it1.hasNext()) {
String key = it1.next();
String value = mm.get(key);
out(key + "..." + value);
}
}
}
//第二种方式,将学生封装成对象,那些第二个集合用Set就可以了
public static void method2() {
//创建学校
HashMap<String, List<Student>> school = new HashMap<String, List<Student>>();
//创建班级
List<Student> ruanjianban = new ArrayList<Student>();
List<Student> yishuban = new ArrayList<Student>();
List<Student> dongmanban = new ArrayList<Student>();
//将班级与学校关联
school.put("软件班", ruanjianban);
school.put("艺术班", yishuban);
school.put("动漫班", dongmanban);
//向每个班级添加学生
ruanjianban.add(new Student("01", "zhangsan"));
ruanjianban.add(new Student("02", "lisi"));
ruanjianban.add(new Student("04", "wanger"));
yishuban.add(new Student("02", "zhangsan1"));
yishuban.add(new Student("01", "zhaoliu"));
dongmanban.add(new Student("05", "wangsan"));
//打印这个学校的学生信息
outInfo1(school);
}
public static void outInfo1(HashMap<String, List<Student>> h) {
//变量出班级名称
Iterator<String> it = h.keySet().iterator();
while(it.hasNext()) {
String key = it.next();
out(key);
Iterator it2 = h.get(key).iterator();
while(it2.hasNext()) {
out(it2.next());
}
}
}
//输出
public static void out(Object obj) {
System.out.println(obj);
}
}
本文深入讲解Java中Map集合的特点、常用方法及其实现原理,并通过具体实例演示如何使用Map集合来解决实际问题。
962

被折叠的 条评论
为什么被折叠?



