Set
612字约2分钟
2024-08-08
Map
用于存储 key-value
的映射,对于充当 key
的对象,是不能重复的,并且,不但需要正确覆写 equals()
方法,还要正确覆写 hashCode()
方法
如果我们只需要存储不重复的 key
,并不需要存储映射的 value
,那么就可以使用 Set
Set用于存储不重复的元素集合,它主要提供以下几个方法
将元素添加进
Set<E>
:boolean add(E e)
将元素从
Set<E>
删除:boolean remove(Object e)
判断是否包含元素:
boolean contains(Object e)
public static void main(String[] args) {
Set<String> set = new HashSet<>();
System.out.println(set.add("A")); // true
System.out.println(set.add("B")); // true
System.out.println(set.add("B")); // false,添加失败,元素已存在
System.out.println(set.contains("A")); // true
System.out.println(set.contains("b")); // false,元素不存在
System.out.println(set.remove("C")); // false,删除失败,元素不存在
System.out.println(set.size()); // 2,总共有两个元素
}
Set
实际上相当于只存储 key
、不存储 value
的 Map
。我们经常用 Set
用于去除重复元素
因为放入 Set
的元素和 Map
的 key
类似,都要正确实现 equals()
和 hashCode()
方法,否则该元素无法正确地放入 Set
最常用的 Set
实现类是 HashSet
,实际上,HashSet
仅仅是对 HashMap
的一个简单封装,它的核心代码如下
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable{
// HashMap
private transient HashMap<E,Object> map;
// 放入 HashMap 的 value
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT) == null;
}
public boolean contains(Object o) {
return map.containsKey(o);
}
public boolean remove(Object o) {
return map.remove(o) == PRESENT;
}
TreeSet
Set接口并不保证有序,而SortedSet接口则保证元素是有序的
HashSet
是无序的,因为它实现了Set
接口,并没有实现SortedSet
接口TreeSet
是有序的,因为它实现了SortedSet
接口
HashSet
输出的顺序既不是添加的顺序,也不是 String
排序的顺序,在不同版本的 JDK
中,这个顺序也可能是不同的
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("pear");
set.add("orange");
for (String s : set) {
System.out.println(s);
}
}
使用 TreeSet
时,输出就是有序的,这个顺序是元素的排序顺序
和使用 TreeMap
的要求一样,添加的元素必须正确实现 Comparable
接口,如果没有实现 Comparable
接口,那么创建 TreeSet
时必须传入一个 Comparator
对象
public static void main(String[] args) {
Set<String> set = new TreeSet<>();
set.add("apple");
set.add("banana");
set.add("pear");
set.add("orange");
for (String s : set) {
System.out.println(s);
}
}