Set接口java.util.Set 不包含重复元素的集合、不能保证存储的顺序、只允许有一个 null。
public interface Set
extends Collection
抽象方法,都是继承自 java.util.Collection 接口。
Set 集合的实现类有很多,在此我们重点了解 HashSet 、 TreeSet 、 LinkedHashSet。
不允许使用索引:Set集合中没有提供使用索引来访问元素的方法,因为元素没有固定的顺序。
非同步:不是线程安全的。
HashSet:基于哈希表实现,具有O(1)的平均时间复杂度的查找、插入和删除操作。
TreeSet:基于红黑树实现,具有排序功能,元素会按照自然排序或指定的比较器顺序进行排序。
LinkedHashSet:基于哈希表和链表实现,保留元素的插入顺序,具有O(1)的平均时间复杂度的查找、插入和删除操作。
public class HashSet
extends AbstractSet
implements Set, Cloneable, Serializable
实现了 Set 接口,底层实现是 HashMap 。不保证迭代顺序,允许 null 元素。
| HashSet() | 构造一个新的空集合; 底层实现HashMap实例具有默认初始容量(16)和负载因子(0.75)。 |
|---|---|
| HashSet(Collection c) | 构造一个包含指定集合中的元素的新集合 |
| HashSet(int initialCapacity) | 构造一个新的空集合,默认初始容量(initialCapacity)和负载因子(0.75) |
| HashSet(int initialCapacity, float loadFactor) | 构造一个新的空集合; 底层HashMap实例具有指定的初始容量和指定的负载因子 |
TreeSetpublic class TreeSet
extends AbstractSet
implements NavigableSet, Cloneable, Serializable
就是说a.compareTo(b) == 0,如果是 true ,那么 add(a) 之后的 add(b) 将会返回 false ,也就是添加失败。
| ceiling(E e) | E | 返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回null。 |
|---|---|---|
| floor(E e) | E | 返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回null。 |
| – | – | – |
| headSet(E toElement) | SortedSet<[E]> | 返回此集合中元素严格小于toElement的部分的视图。 |
| – | – | – |
| tailSet(E fromElement) | SortedSet<[E]> | 返回此集合中元素严格大于或等于fromElement的部分的视图。 |
| – | – | – |
| higher(e) | E | 返回此集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回null |
| – | – | – |
| higher(e) | lower(e) | 返回此集合中严格小于给定元素的最大元素,如果没有这样的元素,则返回null。 |
TreeSet set = new TreeSet(List.of("null", "a", "a", "b", "c", "e", "f",
"g"));
System.out.println(set); // [a, b, c, e, f, g, null]
// 返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回null。
String ceiling = set.ceiling("d");
System.out.println(ceiling);// e
// 返回当前在此集合中的第一个(最低的)元素。
String first = set.first();
System.out.println(first); // a
// 返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回null。
String floor = set.floor("d");
System.out.println(floor); // c
// 返回此集合中元素严格小于toElement的部分的视图。
SortedSet headSet = set.headSet("c");
System.out.println(headSet); // a, b
// 返回此集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回null。
String higher = set.higher("c");
System.out.println(higher); // e
// 返回此集合中元素严格大于或等于fromElement的部分的视图。
SortedSet tailSet = set.tailSet("c");
System.out.println(tailSet); // c, e, f, g, null
// 迭代
for (Object obj : set){
System.out.println(obj);
}
LinkedHashSetpublic class LinkedHashSet
extends HashSet
implements Set, Cloneable, java.io.Serializable
Iterator接口Iterator接口概述Iterator接口表示对集合进行迭代的迭代器。Iterator接口为集合而生,专门实现集合的遍历。主要有两个方法:
package collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* 创建一个Map,完成以下操作:
* 将我国省份和其简称存到 Map 集合中
* 将省份名称中包含"江"的省份从集合中删除
* 遍历输出集合元素
*/
public class Basic {
public static void main(String[] args) {
Map map=new HashMap();
map.put("北京", "京");
map.put("上海", "沪");
map.put("天津", "津");
map.put("重庆", "渝");
map.put("河北", "冀");
map.put("山西", "晋");
map.put("辽宁", "辽");
map.put("吉林", "吉");
map.put("黑龙江", "黑");
map.put("江苏", "苏");
map.put("浙江", "浙");
map.put("安徽", "皖");
map.put("福建", "闽");
map.put("江西", "赣");
map.put("山东", "鲁");
map.put("河南", "豫");
map.put("湖北", "鄂");
map.put("湖南", "湘");
map.put("广东", "粤");
map.put("海南", "琼");
map.put("四川", "川");
map.put("贵州", "黔");
map.put("云南", "滇");
map.put("陕西", "陕");
map.put("甘肃", "甘");
map.put("青海", "青");
map.put("台湾", "台");
map.put("内蒙古", "蒙");
map.put("广西", "桂");
map.put("西藏", "藏");
map.put("宁夏", "宁");
map.put("新疆", "新");
map.put("香港", "港");
map.put("澳门", "澳");
System.out.println(map.size());
//将省份名称中包含"江"的省份从集合中删除
Set> entries = map.entrySet();
Iterator> iterator = entries.iterator();
while (iterator.hasNext()){
Map.Entry next = iterator.next();
if (next.getKey().contains("江")){
iterator.remove();
}
}
//遍历
for (String key:map.keySet()) {
System.out.println(key);
}
System.out.println(map.size());
}
}
Map接口Map 接口不是 Collection 的子接口,使用键、值映射表来存储。
public interface Map
`JDK9` 提供了创建不可修改 Map 对象的方法:
1. Map.of
2. Map.ofEntries
3. Map.copyOf
Map 的实现类较多,在此我们关注 HashMap 、 TreeMap 、 HashTable 、 LinkedHashMap
TreeMappublic class TreeMap
extends AbstractMap
implements NavigableMap, Cloneable, Serializable
AbstractMap ,一个红黑树基于 NavigableMap 实现key 不能存 null ,但是 value 可以存 nullkey 必须是可比较的 (实现Comparable 接口,传递一个 Comparator 比较器)
HashTablepublic class Hashtable
extends Dictionary
implements Map, Cloneable, Serializable

public synchronized V put(K key, V value) {
// 值不能为 null
if (value == null) {
throw new NullPointerException();
}
// 确认 key 不在 hashtable 中存在
Entry,?> tab[] = table;
// 计算 key 的 hash
int hash = key.hashCode();
// 找 key 应在存放在 数组中的位置
int index = (hash & 0x7FFFFFFF) % tab.length;
// index 位置的元素的 key 和 当前的 key 不一样
@SuppressWarnings("unchecked")
Entry entry = (Entry)tab[index];
for(; entry != null ; entry = entry.next) {
// 判断 key 是否相同
if ((entry.hash == hash) && entry.key.equals(key)) {
// 当 key 一样时,替换值
V old = entry.value;
entry.value = value;
return old;
}
}
// 当 key 在 hashtable 中不存在时,添加
addEntry(hash, key, value, index);
return null;
}
private void addEntry(int hash, K key, V value, int index) {
Entry,?> tab[] = table;
// 判断是否需要 "扩容"
if (count >= threshold) {
// 对数组进行扩容 (2n + 1),将原有元素重新计算 hash
rehash();
tab = table;
// 将当前的 key 也重新计算 hash
hash = key.hashCode();
index = (hash & 0x7FFFFFFF) % tab.length;
}
// 原来数组中的 entry 对象
@SuppressWarnings("unchecked")
Entry e = (Entry) tab[index];
// 创建一个 新的 entry 对象, 放到 数组中
tab[index] = new Entry<>(hash, key, value, e);
// 元素个数 +1
count++;
// 修改次数 +1
modCount++;
}