Map集合,HashMap和HashTable的区别,集合嵌套
Map集合
(1)概述:
Map称为双列集合,由键和值组成
假如我有这种数据
键 值
000---------------------张三
001----------------------李四
002----------------------王五
Java针对这种键值映射关系的数据,给我们提供了另外一种容器Map,用来存储这种键值映射关系的数据
Map 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
所有Map集合的数据结构,只跟键有关,跟值没关系,一个键只能映射一个值,键相同,值覆盖
当我们第一次存储键值对数据时,返回的是null。
当我们再次存储一个键相同的数据时,会覆盖掉旧值,返回值是上一次这个键所对应的旧值
(2)举例:
public class Demo6 {
public static void main(String[] args) {
HashMap<String, String> str = new HashMap<>();
String 张三 = str.put("000", "张三");
String 李四 = str.put("000", "李四");
str.put("001", "李五");
str.put("002", "李六");
System.out.println(张三);//返回一个null值
System.out.println(李四);//会覆盖掉上一个相同的键的值,但是返回值是上一次这个键对应的旧值
System.out.println(str);
}
}
结果:
null
张三
{000=李四, 001=李五, 002=李六}
(3)功能描述
a:添加功能
V put(K key,V value):添加元素。这个其实还有另一个功能?替换
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
b:删除功能
void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回
c:判断功能
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
d:获取功能
Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
V get(Object key):根据键获取值
Set keySet():获取集合中所有键的集合
Collection values():获取集合中所有值的集合
e:长度功能
int size():返回集合中的键值对的对数
HashMap()
(1)概述:
HashMap 键的 数据结构是哈希表,键唯一(键唯一靠键重写equals方法来保证,合理的 重写hashCode方法是想让元素减少碰撞) 且无序
HashMap 允许存储null键和null值 线程不安全效率高
(2)举例:
public class Demo5 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("文章", "马伊琍");
map.put("贾乃亮", "李小璐");
map.put("陈思成", "佟丽娅");
map.put("大郎", "金莲");
map.put("222", "金莲");
map.put("333", "金莲");
map.put("444", "金莲");
map.put("555", "金莲");
//遍历方式1
Set<String> keySet = map.keySet();
for (String key : keySet) {
System.out.println(key+"===="+map.get(key));
}
System.out.println("---------------------------------");
//遍历方式2
//获取出,键值对 对象 的集合
Set<Map.Entry<String, String>> entries = map.entrySet();
//遍历键值对 集合 ,通过键值对 对象 里面的方法取出键和值
for (Map.Entry<String, String> entry : entries) {
String key = entry.getKey();//获取键
String value = entry.getValue();//获取值
System.out.println(key+"====="+value);
}
}
}
结果:
贾乃亮李小璐
222金莲
333金莲
444金莲
文章马伊琍
555金莲
陈思成佟丽娅
大郎金莲
注意:
HashSet的遍历方法有两种
第一种是获取键的集合,然后遍历,根据键使用get()方法获得值。
第二种是使用entrySet()方法获取出键值对对象 的集合,然后遍历,分别获得键和值。
LinkedHashMap
(1)特点
键唯一且有序,链表保证了键有序,哈希表保证了键唯一。
(2)举例:
public class Demo5 {
public static void main(String[] args) {
LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put(10,"abc");
linkedHashMap.put(10,"acc");
linkedHashMap.put(20, "abc");
linkedHashMap.put(30, "abc");
linkedHashMap.put(40, "abc");
linkedHashMap.put(50, "abc");
linkedHashMap.put(60, "abc");
linkedHashMap.put(70, "abc");
linkedHashMap.put(70, "abcdddd");
System.out.println(linkedHashMap);
}
}
结果:
{10=acc, 20=abc, 30=abc, 40=abc, 50=abc, 60=abc, 70=abcdddd}
(3)Hashtable和HashMap 的区别
HashMap 允许存储null键和null值 线程不安全效率高
Hashtable 不允许null键和null值 线程安全效率低
Hashtable<String, String> hashtable = new Hashtable<>();
hashtable.put(null,“abc”); 报错,不允许null键和null值
TreeMap
(1)特点:
键的数据结构是二叉树,键唯一,且可以对键进行排序
TreeMap 键不允许插入null
(2)举例:
public class Demo6 {
public static void main(String[] args) {
TreeMap< Student,Integer> str = new TreeMap<>();
str.put(new Student("张三",20),1);
str.put(new Student("张三",25),2);
str.put(new Student("龙五",20),6);
str.put(new Student("李四",21),3);
str.put(new Student("王五",22),8);
str.put(new Student("赵六",23),1);
Set<Map.Entry<Student, Integer>> entries = str.entrySet();
for (Map.Entry<Student, Integer> entry : entries) {
Student key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"-----"+value);
}
}
static 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 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);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
int i = this.age - o.age;
int i1=i==0?this.name.compareTo(o.name):i;
return i1;
}
}
}
结果:
Student{name=‘张三’, age=20}-----1
Student{name=‘龙五’, age=20}-----6
Student{name=‘李四’, age=21}-----3
Student{name=‘王五’, age=22}-----8
Student{name=‘赵六’, age=23}-----1
Student{name=‘张三’, age=25}-----2
集合嵌套
public class Demo5 {
public static void main(String[] args) {
//集合嵌套
//基础班 张三 20
// 李四 21
//就业班 王五 22
// 赵六 23
//HashMap嵌套HashMap
HashMap<String, Integer> jichu = new HashMap<>();
jichu.put("张三",20);
jichu.put("李四",21);
HashMap<String , Integer > jiuye = new HashMap<>();
jiuye.put("王五",22);
jiuye.put("赵六",23);
HashMap<String , HashMap<String , Integer >> java = new HashMap<>();
java.put("基础班",jichu);
java.put("就业班",jiuye);
Set<Map.Entry<String, HashMap<String, Integer>>> entries = java.entrySet();
for (Map.Entry<String, HashMap<String, Integer>> entry : entries) {
String key = entry.getKey();
HashMap<String, Integer> value = entry.getValue();
System.out.println(key);
Set<Map.Entry<String, Integer>> entries1 = value.entrySet();
for (Map.Entry<String, Integer> str: entries1) {
String key1 = str.getKey();
Integer value1 = str.getValue();
System.out.println("\t"+key1+"\t"+value1);
}
System.out.println();
}
}
}
结果:
就业班
王五 22
赵六 23
基础班
李四 21
张三 20
分析:
集合里面套集合,分清楚套与被套的集合分别是什么类型的,遍历的时候里层和外层分开遍历