集合之五:Set接口
set接口的简单介绍
set接口在API中的说明是:一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2)
的元素对 e1
和 e2
,并且最多包含一个 null 元素。
Set里存放的对象是无序,不能重复的,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中。
特点:
- 它不允许出现重复元素(根据对象的equals()方法判断是否重复)
- 不保证集合中元素的顺序
- 允许包含值为null的元素,但最多只能有一个null元素
ps:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的。
set接口的实现类
- HashSet
- 底层的数据结构是 哈希表
- 线程不安全 ,存储和取出都比较快
- 存入HashSet中的对象必须实现HashCode()方法
- LinkedHashSet
- 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现
- 迭代顺序会按照元素插入的顺序进行迭代
- 线程不安全
- TreeSet
- TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序。
- 与HashSet的唯一区别是 :TreeSet可以确保集合元素处于排序状态。
- 线程不安全
哈希表
哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。
String类的hashcode()方法
当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。
总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。
哈希表的存储过程
练习题(答案在后一章)
1、分析以下需求,并用代码实现:
(1)有如下代码:
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("a");
list.add("f");
list.add("b");
list.add("c");
list.add("a");
list.add("d");
}
(2)利用HashSet对list集合去重(最终结果:list中没有重复元素)
2、自己写出contains 方法
3、分析以下需求,并用代码实现: (1)编写一个泛形方法,实现指定位置数组元素的交换 (2)编写一个泛形方法,接收一个任意数组,并反转数组中的所有元素
4.将"goOd gooD stUdy dAy dAy up"
每个单词的首字母转换成大写其余还是小写字母(不许直接输出good good study day day up 要用代码实现)