文章目录
Map接口实现类的特点[很实用]
注意:这里讲的是JDK8的Map接口特点
- Map与Collection并列存在。用于保存具有映射关系的数据:Key - Value(双列元素)
- Map 中的 key 和value 可以是任何引用类型的数据,会封装到 HashMap$Node对象中
- Map 中的 Key 不允许重复,原因和HashSet一样,前面分析过源码
- Map 中的 value 可以重复
- Map 的Key 可以为 null,value 也可以为null,注意 key 为null,只能有一个,value 为null,可以多个。
- 常用String类作为Map的 key(其他类型也都可以 - > Object)
- key 和 value 之间存在单向一对一关系,即通过指定的 key总能找到对应的 value
package com.taotao.map_;
import java.util.HashMap;
import java.util.Map;
/**
* Create By 刘鸿涛
* 2022/1/8 16:34
*/
public class Map_ {
public static void main(String[] args) {
// 解读Map 接口实现类的特点,使用实现类HashMap
// 1. Map与Collection并列存在。用于保存具有映射关系的数据:Key - Value(双列元素)(无序)
Map map = new HashMap();
map.put("no1","涛涛"); //key - value 键对值
map.put("no2","张无忌"); //key - value
// 2. Map 中的 key 和value 可以是任何引用类型的数据,会封装到 HashMap$Node对象中
// 3. Map 中的 Key 不允许重复,原因和HashSet一样,前面分析过源码
map.put("no1","张三丰");
System.out.println(map); //当有相同的key,就会替换 ,张无忌,张三丰
// 4. Map 中的 value 可以重复
map.put("no3","张三丰");
System.out.println(map);
// 5. Map 的Key 可以为 null,value 也可以为null,注意 key 为null,只能有一个,value 为null,可以多个。
map.put("null","null");
map.put("no4","小李子");
System.out.println(map); //张无忌 张三丰 张三丰 null 小李子
// 6. 常用String类作为Map的 key
map.clear();
map.put(1,5); //ok
System.out.println(map); //1 = 5
// 7. key 和 value 之间存在单向一对一关系,即通过指定的 key总能找到对应的 value
//通过get方法传入一个key,会返回对应的value
map.put("no5","刘鸿涛");
System.out.println(map.get("no5")); //刘鸿涛
}
}
- Map存放数据的key - value示意图,一对key - value是放在一个Node中的,又因为Node 实现了 Entry接口,有些书上也说 一对k - v 就是一个Entry
package com.taotao.map_;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Create By 刘鸿涛
* 2022/1/8 17:17
*/
public class MapSource_ {
public static void main(String[] args) {
Map map = new HashMap();
map.put("no1","涛涛");; //k-v
map.put("no2","张无忌"); //k-v
//解读
//1.k - v 最后是 HashMap$Node node = newNode(hash, key, value, null)
//2.k - v 为了方便程序员的遍历,还会 创建 EntrySet 集合,该集合 存放的元素的类型 Entry,而一个Entry对象
// 就有 k,v EntrySet<Entry<K,V>>
//3. entrySet 中,定义的类型是 Map.Entry,但是实际上存放的还是 HashMap$Node
// 这是因为 HashMap$Node implements Map.Entry
//4.当把 HashMap$Node 对象 存放到 entrySet 就方便我们遍历,因为 Map.Entry 提供了两个重要方法
// 1.getKey() 2.getValue
Set set = map.entrySet();
System.out.println(set.getClass()); //HashMap$EntrySet
for (Object obj: set){
// System.out.println(obj); //no2=张无忌 ,no1=涛涛
// System.out.println(obj.getClass()); //HashMap$Node
//1.先做一个向下转型
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getKey() + "-" + entry.getValue());
}
Set set1 = map.keySet();
System.out.println(set1.getClass());
Collection values = map.values();
System.out.println(values.getClass()); //运行类型
}
}
Map接口和常用方法
- put:添加
- remove:根据键删除映射关系
- get:根据键获取值
- size:获取元素个数
- isEmpty:判断是否为空集合
- clear:清除
- containsKey:查找键是否存在
package com.taotao.map_;
import java.util.HashMap;
import java.util.Map;
/**
* Create By 刘鸿涛
* 2022/1/8 18:21
*/
public class MapMethod {
public static void main(String[] args) {
Map map = new HashMap();
// 1. put:添加
map.put("1","2");
map.put("2","2");
System.out.println(map); //1 = 2; //2 = 2
// 2. remove:根据键删除映射关系
map.remove("1");
System.out.println(map); //2 = 2
// 3. get:根据键获取值
System.out.println(map.get("2")); //2
// 4. size:获取元素个数
System.out.println(map.size()); //1
// 5. isEmpty:判断是否为空集合
System.out.println(map.isEmpty()); //false
// 6. clear:清除
// map.clear();
// 7. containsKey:查找键是否存在
System.out.println(map.containsKey("2")); //true
System.out.println(map.containsValue("2")); //true
}
}
Map集合遍历方式
import com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* create by 刘鸿涛
* 2022/4/14 22:20
*/
@SuppressWarnings({"all"})
public class text {
public static void main(String[] args) {
HashMap hashMap = new HashMap();
//给集合添加数据,使用for循环添加五个数据,key为i,值为字符形式i + 0
for (int i = 0; i < 5; i++) {
hashMap.put(i,i + "0");
}
//keySet()
//我们使用keySet()方法创创建set对象,得到hshMap的key值
Set set = hashMap.keySet();
//增强for遍历key,value
for (Object key:set
) {
System.out.println(key + "-" +hashMap.get(key));
}
System.out.println("==============================");
//迭代器遍历map集合
Iterator iterator = set.iterator();
while(iterator.hasNext()){
Object key = iterator.next();
System.out.println(key + "-" + hashMap.get(key));
}
System.out.println("==================entrySet===========");
//entrySet
//just output
Set set1 = hashMap.entrySet();
System.out.println("===============just output============");
System.out.println(set1);
//增强for
System.out.println("==========增强for==========");
for (Object obj:set1
) {
System.out.println(obj);
}
//迭代器
System.out.println("=============迭代器=============");
Iterator iterator1 = set1.iterator();
while(iterator1.hasNext()){
System.out.println(iterator1.next());
}
//这里因为set1被迭代器执行过,所以我们上个迭代器被清零了,需要新建一个迭代器对象
Set set2 = hashMap.entrySet();
Iterator iterator2 = set2.iterator();
//迭代器entrySet格式化输出
System.out.println("=========entrySet格式化遍历=========");
while(iterator2.hasNext()){
Map.Entry key= (Map.Entry)iterator2.next();
System.out.println(key.getKey() + "," + key.getValue());
}
}
}
HashMap扩容机制(红黑树)
HashMap与HashSet扩容机制一样 我就不再叙述了
Hashtable类
Hashtable 和 HashMap对比
版本 | 线程安全(同步) | 效率 | 允许null键null值 | |
---|---|---|---|---|
HashMap | 1.2 | 不安全 | 快 | 可以 |
Hashtable | 1.0 | 安全 | 慢 | 不可以 |
Hashtable扩容机制
Properties类
基本介绍
- Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值对的形式来保存数据(不能为null)
- 它的使用特点和Hashtable类似
- Properties 还可以用于 从xxx.properties 文件中,加载数据到Properties类对象,并进行读取和修改
- 工作后 xxx.properties 文件通常作为配置文件,这个知识点在IO流举例,有兴趣可先看文章
Proprties类基本方法
package com.taotao.map_;
import java.util.Map;
import java.util.Properties;
/**
* Create By 刘鸿涛
* 2022/1/9 17:11
*/
public class PropertiesMethod {
public static void main(String[] args) {
Map map = new Properties();
map.put("1","2");
map.put("2","3");
//通过k 获取对应值
System.out.println(map.get("1")); //2
//删除
map.remove("1");
System.out.println(map); //{2=3}
//修改
map.put("2","4");
System.out.println(map); //{2=4}
}
}
TreeMap类
package com.taotao.map_;
import java.util.Comparator;
import java.util.TreeMap;
/**
* Create By 刘鸿涛
* 2022/1/9 19:22
*/
public class TreeMap_ {
public static void main(String[] args) {
//使用默认构造器,TreeMap(),默认字母升序
// TreeMap treeMap = new TreeMap();
//使用有参构造器 TreeMap(new Comparator())
TreeMap treeMap = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//key字母降序排列
// return ((String)o2).compareTo((String)o1);
//key长度排序
return ((String)o2).length() - ((String)o1).length();
}
});
treeMap.put("jack","杰克");
treeMap.put("taotao","涛涛");
treeMap.put("kristina","克里斯提娜");
treeMap.put("smith","斯密斯");
treeMap.put("liuliu","刘鸿涛"); //如果是长度相等,则会替换value 涛涛-刘鸿涛
System.out.println(treeMap);
}
}
开发中如何选择集合实现类(实战经验)
- 在开发中,选择什么集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行选择,分析如下
-
先判断存储的类型(一组对象[单列]或一组键值对[双列])
-
一组对象【单列】:Collection接口
允许重复:List
增删多:LinkedList【底层维护了一个双向链表】
改查多:ArrayList【底层维护Object类型的可变数组】
不允许重复:Set
无序:HashSet 【底层是HashMap,维护了一个哈希表 即(数组 + 链表 + 红黑树)】
排序:TreeSet
插入和取出顺序一致:LinkedHashSet【底层是LinkedHashMap的底层是HashMap(核心)】,维护数组 + 双向链表
-
一组键值对【双列】:Map
- 键无序:HashMap【底层是:哈希表 jdk7: 素组 + 链表,jdk8: 数组 + 链表 + 红黑树】
- 键排序:TreeMap
- 键插入和取出顺序一致:LinkedHashMap
- 读取文件:Properties