四十、Map集合
作者:互联网
1、概述
java.util.Map<K,V> 集合,里面保存的数据是成对存在的,称之为双列集合。存储的数据,我们称为键值对。 之前所学的Collection集合中元素单个单个存在的,称为单列集合。
K:键的数据类型;V:值的数据类型
- 键不能重复,值可以重复
- 键和值是一一对应的,通过键可以找到对应的值
- (键 + 值)一起是一个整体,我们称之为 “键值对” 或者 “键值对对象” ,在Java中叫做 “Entry对象”
2、Map实现类
HashMap:
此前的HashSet底层实现就是HashMap完成的,HashSet保存的元素其实就是HashMap集合中保存的键,底层结构是哈希表结构,具有键唯一,无序,特点。
LinkedHashMap:
底层结构是有链表和哈希表结构,去重,有序
TreeMap:
底层是有红黑树,去重,通过键进行排序
3、Map中常用方法
方法 | 描述 |
---|---|
public V put(K key, V value) |
把指定的键与指定的值添加到Map集合中。也可以做修改操作 |
public V remove(Object key) |
把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。 |
public V get(Object key) |
根据指定的键,在Map集合中获取对应的值。 |
public Set<K> keySet() |
获取Map集合中所有的键,存储到 Set 集合中。 |
Collection<V> values() |
获取Map集合中所有的值,存储到 Collection 集合中。 |
public Set<Map.Entry<K,V>> entrySet() |
获取到Map集合中所有的键值对对象的集合(Set集合)。 |
public boolean containKey(Object key) |
判断该集合中是否有此 key 键。 |
public boolean containValue(Object value) |
判断该集合中是否有此 value 值。 |
4、Map集合遍历
Map集合既不能使用索引来遍历,也不能使用迭代器遍历,如果要进行对Map集合遍历,可以有两种方式:
-
获取健集合 , 拿到每一个键 , 在通过键找到对应值
-
获取键值对对象集合,拿到每一个键值对对象 , 在获取键和值
遍历一:键找值方式
操作步骤:
- 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示:
keyset()
- 遍历键的Set集合,得到每一个键。
- 根据键,获取键所对应的值。方法提示:
get(K key)
遍历图解:
遍历二:键值对对象遍历
即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值
操作步骤:
-
获取Map结合中,所有的键值对(Entry)对象,以Set集合形式返回。使用方法entrySet()。
public Set<Map.Entry<K,V>> entrySet()
-
遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象
-
通过键值对(Entry)对象,获取Entry对象中的键与值。使用方法getKey() getValue()
public K getKey()
public V getValue()
遍历图解:
tips:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。
5、HashMap存储自定义类型
练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键, 家庭住址作为值。
【学生类】
public class Student {
private String name;
private int age;
//构造方法
//get/set
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
【测试类】
public class HashMapTest {
public static void main(String[] args) {
//1,创建Hashmap集合对象。
Map<Student,String> map = new HashMap<Student,String>();
//2,添加元素。
map.put(new Student("lisi",28), "上海");
map.put(new Student("wangwu",22), "北京");
map.put(new Student("wangwu",22), "南京");
//3,取出元素。键找值方式
Set<Student> keySet = map.keySet();
for(Student key: keySet){
String value = map.get(key);
System.out.println(key.toString()+"....."+value);
}
}
}
- 当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法(如果忘记,请回顾HashSet存放自定义对象)。
- 如果要保证map中存放的key和取出的顺序一致,可以使用
java.util.LinkedHashMap
集合来存放。
6、LinkedHashMap
我们知道HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,还要速度快怎么办呢?
在HashMap下面有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构。
代码体现:
public class LinkedHashMapDemo {
public static void main(String[] args) {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("邓超", "孙俪");
map.put("李晨", "范冰冰");
map.put("刘德华", "朱丽倩");
Set<Entry<String, String>> entrySet = map.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
}
/*
邓超 孙俪
李晨 范冰冰
刘德华 朱丽倩
*/
7、TreeMap集合
7.1 概述
TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树;可以对元素的键进行排序,排序方式有两种:自然排序和比较器排序;到时使用的是哪种排序,取决于我们在创建对象的时候所使用的构造方法;
public TreeMap()
:默认使用自然排序
public TreeMap(Comparator<? super K> comparator)
Comparator比较器排序
7.2 自然排序
public static void main(String[] args) {
TreeMap<Integer, String> map = new TreeMap<Integer, String>();
map.put(1,"张三");
map.put(4,"赵六");
map.put(3,"王五");
map.put(6,"酒八");
map.put(5,"老七");
map.put(2,"李四");
System.out.println(map);
}
控制台的输出结果为:
{1=张三, 2=李四, 3=王五, 4=赵六, 5=老七, 6=酒八}
7.3 比较器排序
需求:
- 创建一个TreeMap集合,键是学生对象(Student),值是居住地 (String)。存储多个元素,并遍历。
- 要求按照学生的年龄进行升序排序,如果年龄相同,比较姓名的首字母升序, 如果年龄和姓名都是相同,认为是同一个元素;
实现:
为了保证age和name相同的对象是同一个,Student类必须重写hashCode和equals方法
【Student类】
public class Student {
private int age;
private String name;
//省略get/set..
public Student() {}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
}
【测试类】
public static void main(String[] args) {
TreeMap<Student, String> map = new TreeMap<Student, String>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//先按照年龄升序
int result = o1.getAge() - o2.getAge();
if (result == 0) {
//年龄相同,则按照名字的首字母升序
return o1.getName().charAt(0) - o2.getName().charAt(0);
} else {
//年龄不同,直接返回结果
return result;
}
}
});
map.put(new Student(30, "jack"), "深圳");
map.put(new Student(10, "rose"), "北京");
map.put(new Student(20, "tom"), "上海");
map.put(new Student(10, "marry"), "南京");
map.put(new Student(30, "lucy"), "广州");
System.out.println(map);
}
/*
控制台的输出结果为:
{
Student{age=10, name='marry'}=南京,
Student{age=10, name='rose'}=北京,
Student{age=20, name='tom'}=上海,
Student{age=30, name='jack'}=深圳,
Student{age=30, name='lucy'}=广州
}
*/
标签:Map,name,map,age,四十,Student,集合,public 来源: https://www.cnblogs.com/6ovo6/p/14951655.html