Map集合
Map 集合是按 <键,值> 对的形式存储数据的;
Map中的键经常使用 String,Integer 作为键的类型,极少使用自定义类型作为键(语法上可以,开发中不用)。但是Map中的值可以是自定义类型,或者是数组,或者是集合。
java.util.Map 集合的结构:
相关的Api:-----------------------------------------------------------------------------
- V put(K key, V value) 添加键值对。如果key已存在,则会重写value,并返回前value值。
- V replace(K key, V value) 根据key替换value值,并返回前value值。如果key不存在,则返回null。
- void putAll(Map<? extends K,? extends V> m) 复制其它集合所有元素到该集合来
- V remove(Object key) 根据键删除键值对
- void clear() 删除所有键值对
- V get(Object key) 返回键对应的值,没有则返回null
- Set<K> keySet() 返回所有的键的Set集合(键唯一,所以用Set)
- Collection<V> values() 返回所有的值的Collection集合(值可重复,所以用Collection)
- int size() 返回键值对的对数
- boolean containsKey(Object key) 查键,有则返回true
- boolean containsValue(Object value) 查值,有则返回true
- boolean isEmpty() 判空
- Set<Map.Entry<K,V>> entrySet() 返回一个包含所有键值对的Set 集合
---------------------------------------------------------------------------
import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapTest01 { public static void main(String[] args) { // 创建 Map<K,V>集合对象 (K、V数据类型可以不一致) Map<String,Integer> map = new HashMap<>(); // 增 map.put("设计模式", 88); map.put("java编程思想", 99); map.put("计算机网络",58); map.put("深入了解java虚拟机",99); // 改 (如果key已存在,则会重写value,并返回前value值) Integer result = map.put("深入了解java虚拟机", 88);
// map.replace("深入了解java虚拟机", 88); //JDK1.8新加的方法 System.out.println(result); // 99 System.out.println(map); // {java编程思想=99, 深入了解java虚拟机=88, 设计模式=88, 计算机网络=58} // 删 map.remove("计算机网络"); System.out.println(map); // {java编程思想=99, 深入了解java虚拟机=88, 设计模式=88} // 查值 (无则返回null) Integer integer = map.get("java编程思想"); System.out.println(integer); //99 // 查键-值对数 System.out.println("size:" + map.size()); // size:3 // 获取所有 key,返回一个Set集合 Set<String> keys = map.keySet(); System.out.println(keys); // [java编程思想, 深入了解java虚拟机, 设计模式] // 获取所有 value,返回一个Collection集合 Collection<Integer> values = map.values(); System.out.println(values); // [99, 88, 88] // 判断是否存在该 key boolean flag = map.containsKey("java编程思想"); System.out.println(flag); // true // 判断是否存在该 value boolean flag2 = map.containsValue(60); // false System.out.println(flag2); // 判空 System.out.println(map.isEmpty()); // false // 清空 map.clear(); System.out.println(map.isEmpty()); // true } }
介绍两种遍历方式
import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapTest02 { public static void main(String[] args) { HashMap<String, Integer> map = new HashMap<>(); // 无序、key唯一 map.put("java编程思想",90); map.put("深入了解java虚拟机",80); map.put("算法第四版",100); /* 方式一:键找值遍历 【1】先获取到当前集合的所有的key keySet 【2】遍历Set集合,获取到每一个key 【3】根据key在Map集合中找到对应的value */ Set<String> keys = map.keySet(); // 获取所有 key for (String key : keys) { Integer value = map.get(key); // 由键返值 System.out.println(key + ": " + value); } /* 方式二:调用entrySet()方法,方法中有getKey()、getValue()方法 1.将 Map集合中的每一组键值对,都封装为一个对象,保存这组键值对信息 2.将这些封装好的键值对对象,放入到一个Set集合中 3.遍历这个Set集合,拿到集合中的每一个键值对对象 4.从键值对对象中,将键的信息和值得信息获取出来 */ Set<Map.Entry<String, Integer>> entries = map.entrySet(); //封装为对象,并保存到Set集合中 //System.out.println(entries); // 直接打印 [xxx,xxx,xxx]
// 或者遍历Set集合 for (Map.Entry<String, Integer> entry : entries) { String key = entry.getKey(); // 取key Integer value = entry.getValue(); // 取value System.out.println(key + ":" + value); } } } 运行结果: 算法第四版: 100 java编程思想: 90 深入了解java虚拟机: 80 ------------------------- 算法第四版:100 java编程思想:90 深入了解java虚拟机:80
---------------------------------------------------------
HashTable 的特点
- HashTable 底层是哈希表,它是线程安全的;而 HashMap 不是线程安全的
- HashTable 默认初始化容量:11;而 HashMap 默认初始化容量:16
- 加载因子:0.75。当键值对的数量 > 容量 * 加载因子时扩容
- HashTable 按2倍+1扩容,而 HashMap 按2倍大小扩容
- HashTable 的键与值都不能为null;而 HashMap 的键或者值可以为null
- 在创建 HashTable 时可以指定初始化容量;而 HashMap 也可以指定初始化容量,系统会把 HashMap 的初始化容量调整为2的幂次方,即把17~31之间的数会调整为32,为了快速计算数组的下标。
-----------------------------------------------------
Properties
Properties 继承了 HashTable,键与值都是 String字符串。经常用来设置读取系统属性。
经常使用的方法:
Object setProperty(String key, String value) 添加键值对。如果key已存在,则会重写value,并返回旧value值。
String getProperty(String key) 根据key查找返回对应value值。
------------------------------------------
package cn.powernode.javase.properties; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.ResourceBundle; public class PropertiesTest01 { public static void main(String[] args) throws IOException { // 1、创建 Properties对象 Properties properties = new Properties(); // 2、建立当前程序与配置文件的流通道 InputStream in = Thread.currentThread().getContextClassLoader(). getResourceAsStream ("resources/pro.properties"); // 3、使用 Properties加载流 properties.load(in); //如果出现空指针异常就是配置文件的路径不正确 // 4、读取属性 System.out.println(properties.getProperty("name")); System.out.println(properties.get("pwd")); // 5、关闭流 in.close(); // 也经常使用 ResourceBundle读取配置文件属性,如: ResourceBundle bundle = ResourceBundle.getBundle("resources/pro"); System.out.println( bundle.getString("name")); System.out.println( bundle.getString("pwd")); } }
执行结果:
zs
123456
zs
123456
----------------------------------
TreeMap
TreeMap 实现了 SortedMap接口,可以根据键自然排序。要求键必须是可比较的。
- 比较器排序:在创建 TreeMap 时,通过构造方法指定 Comparator 比较器
- 自然排序:如果没有在构造方法指定 Comparator,要求键实现 Comparable 接口
注意:TreeMap 只能根据键排序,不能根据值排序。排序的原理是红黑树原理,红黑树是一种自平衡二叉树。
具体做法参考:TreeSet 的用法 - 鹿先森JIAN - 博客园 (cnblogs.com)