Java的集合世界中主要由List,Set,Queue,Map构成,我们在之前的博文中已经学习了List,接下来我们继续学习Set集合。Set特点:存取无序,不可以存放重复的元素,不可以用下标对元素进行操作
作为Set容器的代表子类,HashSet经常被用到,我们通过源码去分析它
【源码查看】
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
}
虽然HashSet实现了Set接口,但通过源码我们能够看到,它的底层逻辑实现其实依据的是HashMap,通过操作map的key值来实现元素的增删改查,下面通过一个小测试类去用下HashSet。
【代码示例1】
public class Test {
public static void main(String[] args) throws FileNotFoundException {
// 创建一个新的HashSet
HashSet<Integer> set = new HashSet<>();
// 添加元素
set.add(3);
set.add(4);
set.add(0);
set.add(1);
set.add(4);
// 输出HashSet的元素个数
System.out.println("HashSet size: " + set.size());
// 判断元素是否存在于HashSet中
boolean containsWanger = set.contains(2);
System.out.println(containsWanger);
// 删除元素
boolean removeWanger = set.remove(1);
System.out.println(set);
// 修改元素,需要先删除后添加
boolean removeChenmo = set.remove(3);
boolean addBuChenmo = set.add(4);
System.out.println(removeChenmo && addBuChenmo);
// 输出修改后的HashSet
System.out.println(set);
}
}
输出:
HashSet size: 4
false
[0, 3, 4]
false
[0, 4]
由代码结果进一步证明了我们的结论:1、存储数据不重复,但add重复数据并不报错,原因是第一个数据会被第二次重复数据覆盖掉;2,无序,很多人发现输出了一个有序的数字集合,这个其实与我们所说的有序是有区别的,在Set中的有序无序是指输入的顺序与输出的顺序是否一致 当然,想要实现有序可以通过LinkedHashSet,底层通过链表记录元素插入顺序。
面试考点
这里面其实包含着一个小小的Java面试考点,曾经有面试官问过这样的一个问题:
集合中的无序性和不可能重复性是什么意思?
那么有的小伙伴会问了:“我就想存一个不重复的数据集合,同时又想要他们有序怎么办呢?”,Java的开发人员已经早就为你想到了,这个办法就是用LinkedHashSet!LinkedHashSet 是基于 LinkedHashMap 实现的,并且使用链表维护了元素的插入顺序,具有快速查找、插入和删除操作的优点,又可以维护元素的插入顺序!源码就不带大家看了,咱们直接上测试案例。
【代码示例2】
LinkedHashSet<String> set = new LinkedHashSet<>();
// 添加元素
set.add("Hello");
set.add("Java");
set.add("Build");
set.add("Java");
System.out.println(set);
// 删除元素
set.remove("Hello");
// 修改元素
set.remove("Java");
set.add("java");
// 查找元素
boolean bool = set.contains("Build");
System.out.println("Build哥:" + bool);
//输出
System.out.println(set);
输出:
[Hello, Java, Build]
Build哥:true
[Build, java]
通过输出结果我们可以得出结论:LinkedHashSet中的元素不可重复,有序。
通过上面两个集合类我们大概能够猜到,几乎所有的Set集合的底层都是通过Map去实现,TreeSet同样是基于TreeMap实现,TreeMap 基于红黑树实现,所以TreeSet也就自带了排序功能。
public TreeSet() {
this(new TreeMap<E,Object>());
}
【代码示例3】
public class Test {
public static void main(String[] args) {
// 创建一个 TreeSet 对象
TreeSet<Integer> set = new TreeSet<>();
set.add(3);
set.add(6);
set.add(2);
set.add(1);
set.add(0);
set.add(9);
System.out.println(set);
}
}
输出:
[0, 1, 2, 3, 6, 9]
本文分享自 JavaBuild888 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!