Map集合
概述
生活中存在着许许多多的映射关系,比如一个身份证号对应一个人,一个车牌照对应一辆车,等等.这样的关系还有许多.在Java的世界里,用Map(接口)表示这种一对一的关系.
Map的常用子类
Map接口有许多的实现类,但是常用的只有如下:HashMap,TreeMap,LinkedHashMap;
HashMap<K,V>: 存储数据采用的是哈希表结构,元素的存储顺序是无序的(与HashSet一样),键在Map中的存在是唯一的,所以当使用自定义数据类型的时候需要重写hashCode和equals方法.
TreeMap<K,V>: TreeMap是一种按照键的自然顺序进行存储数据的结构,底层的数据结构是红黑树.
LinkedHashMap<K,V>: 该类是HashMap的子类,存储数据采用的是哈希表+链表的结构,可以保证数据的存储顺序一致,键也是不可以重复的,一样需要重写键的hashCode和equals方法.
Map遍历 的方式
1.keySet()方法,把全部的键当成几个集合返回,通过对键的遍历,结合Map的get()方法,可以拿到所有的值.
2.entrySet()方法:把Map中所有的键值对对象当做set集合返回,对set集合进行遍历,通过getValue()和getKey()方法可以获得值和键.
3.values():可以获取全部的值,返回的是一个Collection集合.
4.Lambda表达式:获取所有键值对.
Map<String,Integer> map = new HashMap<>();
//添加元素
map.put("adb",10);
map.put("aaa",10);
map.put("adb",30);
map.put("abc",10);
//迭代 keySet()
System.out.println("------------ keySet()--------------");
//获取键的set集合
Set<String> keys = map.keySet();
for (String key : keys) {
//通过键获取值
System.out.println("key="+key+",values="+map.get(key));
}
//迭代 entrySet()
System.out.println("----------entrySet()------------");
//获取键值对的set集合
Set<Map.Entry<String,Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
System.out.println("key="+entry.getKey()+",value="+entry.getValue());
}
//迭代 values
System.out.println("----------values---------");
Collection<Integer> values = map.values();
for (Integer value : values) {
System.out.println("value="+value);
}
//Lambda
System.out.println("----------Lambda-----------");
map.forEach((k,v)->{
System.out.println("key="+k+",value="+v);
});
HashMap
HashMap介绍
1.键不重复,若键重复,就会把值覆盖.
2.添加元素的顺序和取出来的顺序不一致,底层实现是哈希表(数组+链表+红黑树).
3.线程不安全
4.可以存储null键和null值
HashMap存储自定义数据类型案例
public class Student {
private String name;
private int age;
//构造方法
//get[表情]t
@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);
}
}
}
LinkedHashMap介绍
1.键不可以重复,通过重写hashCode()方法和equals()方法实现,若键重复,会造成值被覆盖.
2.允许存放null键和null值
3.由于多加了一条链表,所以可以维持存取顺序一致.
4.线程也是不安全的.
public static void main(String[] args) {
LinkedHashMap<Person,String> map = new LinkedHashMap<>();
//V put(K key, V value) 将指定的值与此映射中的指定键关联。
map.put(new Person("abc",23),"abc");
map.put(new Person("add",9),"add");
map.put(new Person("aaa",32),"aaa");
map.put(new Person("aaa",32),"bbb");
map.put(null,null);
//boolean containsKey(Object key) 返回 true如果这Map包含一个指定的键映射。
System.out.println(map.containsKey(new Person("aaa",32)));
//V remove(Object key) 如果存在(可选操作),则从该Map中移除一个键的映射。
System.out.println(map.remove(new Person("aaa",32)));
//V replace(K key, V value) 仅当它当前映射到某一值时,替换指定的键的条目。
System.out.println(map.replace(null,"AAA"));
Set<Person> keys = map.keySet();
for (Person key : keys) {
System.out.println("key="+key+",value="+map.get(key));
}
}
TreeMap介绍
TreeMap是一种可以按照自然顺序或者比较器定义的顺序对存储的键值对对象进行排序的一种Map.TreeMap是不允许存放null键的.因为null没办法进行排序.
排序的实现有两种方法,第一种是添加的元素自身具有比较性,也就是实现Comparable接口.
第二种是集合容器自身具备比较性,若二者同时存在,首选第二种.