在这里要感谢吕老师的贡献
一个简单的HashMap理解图(上图)
-
Map:地图
1. 概念:Map:就是用来装键值对集合的容器
2. 作用:
解决了需要成对出现的这种关系结构
键(key) : 质就是一个数据
值(value) : 本质也是一个数据
键值对: 就是一对(和两个是有区别的),一对一般是有某种关系
例如:
1、例如QQ的账号+密码:想象场景-需要使用一个集合搜集各位100人的QQ号码和密码;
2、银行账户和密码
3、游戏账号和密码
4、搜集各位的姓名+女朋友的姓名 (情侣关系)
5、坐标(x,y)
6、…3. Map的继承体系 是一个独立的体系,跟Collection一毛关系都没有 Map 接口 HashMap :基于hashCode(),底层是Entry键值对的数组,数组中装装的是 键值对, 会根据添加的key的hashCode值 模 当前数组的length(默认是16), (掌握) 而得到数组的下标,进而保存键值对。如果key模length后,得到的下标是相等的,就会发生hash碰撞(哈希冲突),这时候再继续判断key的equals方法, 如果equals判断为true,就会将原来的键值对覆盖, 如果是false,就会在该下标处的原来键值对后面形成 链表,如果链表长度达到8个,就形成 红黑树。 当删除键值对后剩余的数量小于等于6的时候,就重新将红黑树,退化为链表。 (jdk1.8)put添加/remove删除 key判断键是否重复和HashSet判断重复一样:1. hashCode 2.equals() HashMap底层是Entry(键值对)的数组,并且维护了链表和红黑树 HashTable : 就是一个线程安全的HashMap,不能存放null键和null值 Properties:特殊的HashTable(是HashTable子类),只不过key-value都是String类型,一般用来做 配置文件:(解决硬编码问题的文件) 1. .xml 2. .properties 3. .ini/.init 4. .yml (SprintBoot) ConcurrentHashMap : 就是一个线程安全且效率更高的的HashTable,理论上是HashTable的16倍 LinkedHashMap: 就是一个内部维护了一个链表的HashMap,可以保证存入和取出顺序 TreeMap : 判断key重复的规则和TreeSet一样 TreeMap中的键(key)要么是具有自然排序能力(需要key实现Comparable接口,重写CompareTo方法); 或者TreeMap中提供一个比较器Comparetor实现类对象 如果key是自然或者定制排序,返回值是0表示,key是重复的,如果是正数,则按照key的升序排序,否则是降序
-
HashMap底层原理参见source文件夹中的图片
5.遍历HashMap的三种方式:(掌握)1. Set<Map.Entry<K,V>> entrySet() 返回所有键值对的Set集合。 2. Set<K> keySet() 返回所有键的Set集合。 3. Collection<V> values() 返回所有值的Collection集合 步骤: 1. 根据需求调用上面某一个方法,得到(键值对Entry或者键key)Set或者Collection(value)集合 2. 遍历第一步中的Set或者Collection集合 1. foreach 2. 单向迭代器 遍历选择: 如果是既需要key也需要value,最好用entrySet,其他场景根据情况 Map使用选择:(掌握) 1、Map中,HashMap具有超高的访问速度,如果我们只是在Map 中插入、删除和定位元素, 而无关线程安全或者同步问题,HashMap 是最好的选择。 2、如果考虑线程安全或者写入速度的话,可以使用HashTable,JDK8后建议使用ConcurrentHashMap替代HashTable,既能获取超高的访问速度,又能保证线程安全 3、如果想按怎么存的顺序怎么取,比如队列形式,排队,那么使用LinkedHashMap 4、如果需要让Map按照key进行升序或者降序排序,那就用TreeMap
-
Properties类:常用来做配置文件 (掌握)
Properties文件不支持中文,所以,写在文件中的中文看到的是十六进制格式
文件中注释用#,可以通过插件显示中文注释内容1. 概念:就是一个特殊的HashTable,key和value都是String类型,常用来做配置文件 2. 作用: 解决了Java编程中的硬编码问题。 3. 使用:一定要使用Properties自己的方法,才能使key和value都是String类型 3.1. 将内存中的数据,写出到硬盘 void list(PrintStream out) 将此属性列表打印到指定的输出流。 void list(PrintWriter out) 将此属性列表打印到指定的输出流。 存放值方法: setProperty(String key,String value); 3.2. 将硬盘中的数据,读取到内存 void load(InputStream inStream) 从输入字节流读取属性列表(键和元素对)。 void load(Reader reader) 以简单的线性格式从输入字符流读取属性列表(关键字和元素对)。 取值方法: 1. getProperty(String key); 2. getProperty(String key,String defaultValue); 4. 注意: 1. 今天涉及到IO的知识,只管用,不用管其他的 2. key和value不要写中文 3. 不支持中文,文件中注释用#,可以通过插件显示中文注释内容
-
泛型:
1. 概念:就是一个占位符号而已,在设计类的时候,占用位置
就是在设计类(接口等)的时候,没有给规定具体是什么类型的参数,
在实例化或调用的时候再传入具体的类型,告诉编译器这是什么类型。2. 作用: 1. 帮助程序员校验代码(用泛型约束容器中的元素类型),限制类型的使用 2. 避免强制转换 3. 提高程序的扩展性 3. 使用: 1. 泛型类 语法:直接在类名后加上<数据类型>,一般情况下数据类型用字母代替 2. 泛型方法 语法:在修饰符后,返回值前加上<数据类型> 3. 泛型上限和下限 T super Number: 表示T最小类型取值到Number类型 T extends Number: 表示T最大类型取值到Number类型 <? super T> 表示通配符,可以匹配任意类型 4. 泛型嵌套 Set<Map.Entry<K,V>> entrySet() 返回所有键值对的Set集合。 4. 注意事项: 1.泛型数据类型只能是引用类型 2. = 两边<>中的数据必须完全一致,包括顺序 类型擦除(自己查)PECS原则 5. 常见字母含义: E element 元素,一般用在集合等容器类中 T type 类型 K key 键 V value 值 R result 返回值