在java的Collection集合中,除了List接口,Queue接口外,还有Set接口,而Set接口的结构如下
•Set接口常用实现类:
1.HashSet
a.实现了 Set 接口
b.“它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变”
c.允许使用 null 元素
2.LinkedHashSet
a.HashSet的子类
b.由于该实现类对象维护着一个运行于所有元素的双重链接列表,由于该链接列表定义了迭代顺序,所以在遍历该实现类集合时按照元素的插入顺序进行遍历
3.TreeSet
a.既实现Set接口,同时也实现了SortedSet接口,具有排序功能
存入TreeSet中的对象元素需要实现Comparable接口
由于其中HashSet类直接实现了Set接口,所以我们讲一下HashSet类。
-
以HashSet演示Set接口常用方法
1.add(Object obj):向Set集合中添加元素,添加成功返回true,否则返回false
import java.util.HashSet; //引包
public class Test {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>(); //创建HashSet类的set对象
System.out.println(set.add("Tom")); //使用add方法添加元素并返回值
}
}
这里由于添加成功,所以输出即返回值true。我们会发现这与arraylist的add方法有所不同,对于添加成功与否有特定的返回值,我们不禁会觉得奇怪,实际上确实是有原因的,后面会写到。
2.size() :返回Set集合中的元素个数
import java.util.HashSet;
public class Test {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
set.add("Tom"); //add方法添加元素
System.out.println(set.size()); //size方法返回元素个数:1
}
}
3.remove(Object obj) : 删除Set集合中的元素,删除成功返回true,否则返回false
import java.util.HashSet;
public class Test {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
set.add("Tom");
System.out.println(set.size()); //size方法返回值为1
System.out.println(set.remove("Tom")); //remove方法移除Tom元素
System.out.println(set.size()); //再次调用size方法,返回值变为0
}
}
4.isEmpty() :如果Set不包含元素,则返回 true ,否则返回false
import java.util.HashSet;
public class Test {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
set.add("Tom");
System.out.println(set.size());
System.out.println(set.remove("Tom"));
System.out.println(set.size());
System.out.println(set.isEmpty()); //返回值为true,说明set集合中无元素
}
}
5.clear() : 移除此Set中的所有元素
import java.util.HashSet;
public class Test {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
set.add("Tom");
set.clear(); //调用clear方法清除所有元素
System.out.println(set.size()); //size方法返回元素数目:0
}
}
6.iterator() :返回在此Set中的元素上进行迭代的迭代器
import java.util.HashSet;
import java.util.Iterator; //引包
public class Test {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
set.add("Tom");
set.add("Jim");
set.add("Jerry"); //添加三个元素
Iterator<String>iterator = set.iterator(); //将set中的元素存入iterator中
while(iterator.hasNext()) { //循环条件:iterator依然能转到下个元素
System.out.println(iterator.next()); //输出iterator所指向的元素
}
}
}
输出结果为
我们发现并没有按照我们添加元素的顺序输出,这是HashSet类的一个特点“它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变”。
7.contains(Object o):如果Set包含指定的元素,则返回 true,否则返回false
import java.util.HashSet;
public class Test {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
System.out.println(set.contains("Tom")); //调用contains方法判断是否
} //含有Tom元素,因为并不含有
} //返回false
-
注意事项
前面我们说到HashSet调用add方法时需要确定是不是添加成功这点很奇怪,原因就在于HashSet类中创建的集合不能有重复的元素,如果我们强行添加重复元素会怎么样呢?
我们发现,在我们添加第二个”Tom“元素的时候失败了,并且size方法告诉我们这个集合中确实仍然只有一个元素,那么我们需要探访底层代码来查看一下原因。
首先我们点开HashSet无参构造方法
可以看到实际上HashSet的无参构造方法其实创建的是HashMap对象,并且传给了map全局变量。
之后我们再查看add方法
可以看到HashSet的add方法实际上是map调用了put方法,于是我们再查看put方法
可以看到put的数据存到了key里,而key是无法重复的,这也就间接导致了add方法添加的元素不能重复。