Set和Map
Set集合
Set是Collection下面的一个子接口。 Set接口有以下特点: 1. 无索引(不能根据索引获取元素的) 2. 不可重复(不能保存重复元素) 3. 无序的(大部分Set集合满足的特点)(按照什么顺序存,不一定按照什么顺序取) Set是一个接口,如果要用需要使用实现类,Set接口下最常用的实现类是HashSet HashSet满足Set接口的所有的特点(无序,无索引,不可重复) Set集合的遍历。 因为Set集合是没有索引的,所以不能使用普通for遍历,可以使用迭代器或增强for遍历,强烈推荐增强for
01 哈希值
哈希值其实就是一个int数字,我们可以将哈希值看成对象的一个标识(特征码) 在Object中有一个方法叫做hashCode,可以获取对象的哈希值。 int hashCode():获取对象的哈希值。 Object中的hashCode方法,哈希值的计算方式是根据对象的地址值计算的。 对象的哈希值根据地址值计算一般来说意义不大,我们更多的是希望哈希值是根据属性计算的,如果两个对象的属性完全相同, 哈希值也应该相同。 如果想要自己定义哈希值的计算规则,需要重写hashCode方法。 哈希值是对象的一个标识,但并不是唯一的标识,对象的哈希值允许重复。
//重写hashCode方法,自己定义哈希值的计算规则 @Override public int hashCode() { return name.hashCode() * 31 + age; }
02 哈希表
哈希表是一个数组,数组中的每个元素是链表,哈希表可以提高查找效率
03 HashSe唯一性
HashSet判断唯一性的过程
先比较对象的哈希值。 如果哈希值不同,肯定是不同的对象。 如果哈希值相同,不一定是同一个对象。
如果哈希值相同,还会调用equals进行比较。 如果equals的结果是true,表示对象相同。 如果equals的结果是false,表示对象不同
结论: 如果使用HashSet存储自定义对象并保证唯一性(对象的属性相同就看成是同一个对象),需要同时重写hashCode和equals,缺一不可。
Map
Map集合不能通过迭代器或者增强for直接进行遍历。
Map集合有两种遍历方式 keySet方式(键找值)【推荐】 entrySet方式(键值对) 如果要遍历Map集合,我们可以获取到Map集合中所有的键,
将所有的键放入到Set集合中, 然后遍 历Set集合,拿到集合中的每一个键,然后根据键去Map集合中获取对应的值。
HashMap保证唯一性(键)的方式和HashSet是一模一样。
LinkedHashMap是Map接口下一个不常用的实现类,内部除了有一个哈希表之外还有一个链表,链表可以保证有序
Map计数器
map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);