散列表结构 可以理解为 数组中保存的是链表的首节点,用来保存k和v键值对操作
  
 hash算法 : 是一种安全的加密机制,可以把不定长的数据转换为定长数据,并且不能保证其唯一性,又叫哈希冲突
  
  在java中 指的就是hashCode方法
  
  对一个对象生成多次hash值 , 值一定相同 , 多个对象也可能生成相同的hash值,叫哈希冲突
  
  k不可重复 , v 可重复 
  
  添加过程 : 
          1 根据要添加的key,调用的它的hashCode方法,生成hash值
          2 通过一定的算法,根据hash值生成数组的下标
          3 判断该下标中,是否有数据,如果没有数据就把该键值对映射关系保存到数组中
          4 如果该下标中,有数据,则调用key的equals方法,和对应的所有数据进行比较,如果不相等,则添加到链表的尾部即可
          5 如果对应的链表中,通过equals方法比较的时候,发现了相同的数据,那么 key不再添加 ,但是value值会替换原来的value值
          通过添加过程得知,会自动调用该对象的hashCode和equals,所以在保存自定义类型的时候,需要注意方法覆写
          在1.8中有个新改动,为了提高查询效率,引入了红黑树和扩容的优化
              因为链表在查询性能上较差,所以每个数组中的链表个数如果大于等于7,则会把该链表转换为红黑树
              数组默认初始化容量为16
  
  
  在java中 没有散列表的概念,把散列表封装为了HashMap和HashTable

Map是无序的,并且保存的是K-V键值对映射关系,其中K不能重复,V可重复
  
  HashMap : 底层是散列表
  
  TreeMap : 底层是红黑树,元素必须按照一定的规则进行排序
  
  映射关系 : 比如 商品 和 购买数量 , 或者数据统计
              "akshdkjhwqgheghgbsjkasdjaskhrjqw" 统计每个字符出现的个数 使用 HashMap进行存储,字符做K 次数做V

// 特殊的map
		Properties p = new Properties();
		// 添加数据
		p.setProperty("asd", "123");
		// 获取value
		p.getProperty("asd");

TreeMap 保存的元素会按照一定规则进行排序,底层是红黑树
  
 Comparable 和 Comparator

泛型 : 在编译过程中检测数据类型是否匹配
  
  泛型 必须是引用类型,不能使用基本类型
  
  优点 : 统一了数据类型,减少了类型转换
  
  缺点 : 只能保存同一种类型

定义泛型,使用大写字母A-Z表示,写什么都一样,都只是占位符而已,只不过 某些字符也有一些特殊的含义
          E : Element 一般代表元素,而集合中的数据 我们叫元素,所以在集合中出现的泛型一般使用E表示
          K : Key 表示键
          V : value 表示值 K和V一般在散列表中出现(Map)
          T : Type 表示一个java类型
          N : 表示Number
          ? : 表示不确定的类型
  
  如果规定了泛型,但是使用的地方没有指定泛型,则默认为Object类型

Map以Value进行排序
  
  Map是没有办法按照value排序的,因为源码中写死了 是用key进行比较
  
  所以 只能保存到List中进行排序