Set
概述:
-
属于Collection下的一个无序子接口
-
一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。
-
特点:
- 无序没有位置的概念,没有先后顺序,没有编号
- 无索引
- 不能重复
-
实现类:
- HashSet
- TreeSet
-
存储特点:
- 相同的元素并没有存储到集合中
- Set集合不保证输出的顺序和存储的顺序一致
-
Set的遍历:
- Set集合中没有特有的方法,全部直接使用从Collection中继承来的方法
- 遍历方法也只是使用Collection中的遍历方式
-
四种遍历方式:
-
转数组,变成数组的遍历(不带泛型)
- Object[] toArray()
-
转数组,变成数组的遍历(不带泛型)
- T[] toArray(T[] ts)
- T[] toArray(T[] ts)
-
迭代器
-
增强for循环
-
格式
- for(容器中的数据类型 元素名称 : 你要遍历的容器){
直接操作上面的元素名称;
}
- for(容器中的数据类型 元素名称 : 你要遍历的容器){
-
底层本质:任然是一个迭代器
- 不能使用集合对象增删元素(避免并发修改)
- 不能使用迭代器增删元素(无法获得迭代器)
- 不能修改集合元素(没有拿到元素的位置,拿到的是值,但可以修改集合中记录的引用对象)
- 快捷键:fore + alt + /
-
Iterator是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出java.util.ConcurrentModificationException异常。
-
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。
-
但你可以使用 Iterator 本身的方法 remove() 来删除对象,Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。
-
-
正确的在遍历的同时删除元素的姿势:
Iterator<Student> stuIter = students.iterator();
while (stuIter.hasNext()) {
Student student = stuIter.next();
if (student.getId() == 2)
stuIter.remove();//这里要使用Iterator的remove方法移除当前对象,如果使用List的remove方法,则同样会出现ConcurrentModificationException
}
对以下代码进行反编译
for (Integer integer : set) {
System.out.println(integer);
}
Integer integer;
for (Iterator iterator = set.iterator(); iterator.hasNext(); System.out.println(integer))
integer = (Integer)iterator.next();
Integer i; 定义一个临时变量i
Iterator iterator = set.iterator(); 获取set的迭代器
iterator.hasNext(); 判断迭代器中是否有未遍历过的元素
integer = (Integer)iterator.next(); 获取第一个未遍历的元素,赋值给临时变量i
System.out.println(integer) 输出临时变量integer的值
Set的实现类
-
概述
-
实现类:HashSet
- 使用哈希存储的方式,哈希表实现,链式存储和顺序存储的中和
- 查询和添加都是比较快的
- 保证元素的唯一
-
** HashSet保证元素唯一性原理的探究**
hashSet集合不能存入相同元素。
无序存放(散列) 存入自定义对象时要同时重写equals和hashCode方法判断对象是否相同
Hashset保证元素唯一性原理总结
hashCode的重写
LinkedHashSet
- **LinkedHashSet是HashSet的子类,能够保证存储的顺序和取出的顺序一样 **
- 实现的原理:
- 每个节点,增加一个地址域,存储逻辑上的下一个节点的地址。
- 作用:
- 既要保证顺序,又要去重
List<Integer> list = new ArrayList<Integer>();
list.add(123);
list.add(888);
list.add(666);
list.add(666);
list.add(888);
list.add(123);
list.add(123);
System.out.println(list);
LinkedHashSet<Integer> lsh = new LinkedHashSet<Integer>(list);
System.out.println(lsh);
结果: