集合框架提供三种类型的集合:
- 数学集
- 排序集
- 导航集
Set集合框架结构:
一、数学集
- Set 接口对数学中的一组进行建模。集合是唯一元素的集合。
- Java最多允许一个Set中的一个空元素。 Set 中元素的排序并不重要。
- Java不保证 Set 中元素的排序。
- 当循环遍历 Set 的所有元素时,你得到 Set 中的每个元素一次。
主要实现类
- HashSet:为快速查找设计的Set。是哈希表结构,主要利用HashMap的key来存储元素,计算插入元素的hashCode来获取元素在集合中的位置;
- LinkedHashSet:具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。
1.HashSet
@Test
public void test1() {
Set<String> s1 = new HashSet<>();
s1.add("1");
s1.add("2");
s1.add("3");
s1.add("1");
Set<String> s2 = new HashSet<>(s1);
s2.add("a");
s2.add("b");
s2.add("c");
s2.add(null);
s2.add(null);
System.out.println("s1: " + s1);
System.out.println("s2: " + s2);
}
输出:
s1: [1, 2, 3]
s2: [null, 1, a, 2, b, 3, c]
2.LinkedHashSet
集合框架提供 LinkedHashSet
类作为 Set 接口的另一个实现类。
HashSet
不保证顺序元素。 LinkedHashSet
在插入元素时保持元素顺序。
@Test
public void test2() {
Set<String> s1 = new LinkedHashSet<>();
s1.add("1");
s1.add("2");
s1.add("3");
s1.add("1");
System.out.println("s1: " + s1);
Set<String> s2 = new LinkedHashSet<>(s1);
s2.add("a");
s2.add("b");
s2.add("c");
s2.add(null);
s2.add(null);
System.out.println("s2: " + s2);
}
输出:
s1: [1, 2, 3]
s2: [1, 2, 3, a, b, c, null]
二、排序集
- 排序集是在其元素上有排序的集合。
SortedSet
接口表示Java集合中的排序集合框架。- 排序集中的元素可以按照自然顺序排序
Comparable
接口或使用自定义排序Comparator
。 - 如果指定了
Comparator
自定义排序,则忽略Comparable
接口。
TreeSet 类是Collection框架中SortedSet接口的一个实现。
自然排序
例子1
String 类实现 Comparable 接口。SortedSet将使用 Comparable 接口及其 compareTo()方法对String值进行排序。
@Test
public void test3() {
SortedSet<String> set = new TreeSet<>();
set.add("d");
set.add("b");
set.add("a");
set.add("c");
System.out.println(set);
}
输出:
[a, b, c, d]
自定义排序
例子2
通过Comparable
接口可以实现定制排序。
class M implements Comparable<M>{
int age;
public M(int age)
{
this.age = age;
}
public String toString()
{
return "M[age:" + age + "]";
}
@Override
public int compareTo(M o) {
//按照年龄排序
return this.getAge() - o.getAge();
}
}
public class Main {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new M(5));
ts.add(new M(-3));
ts.add(new M(9));
System.out.println(ts);
for(Iterator iter = ts.iterator(); iter.hasNext();){
Object value = iter.next();
System.out.println(value);
}
}
}
输出:
[M[age:9], M[age:5], M[age:-3]]
M[age:9]
M[age:5]
M[age:-3]
例子3
通过Comparator
接口可以实现定制排序。
public class Main {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new Comparator()
{
//根据M对象的age属性来决定大小
public int compare(Object o1, Object o2)
{
M m1 = (M)o1;
M m2 = (M)o2;
return m1.age > m2.age ? -1 : m1.age < m2.age ? 1 : 0;
}
});
ts.add(new M(5));
ts.add(new M(-3));
ts.add(new M(9));
System.out.println(ts);
for(Iterator iter = ts.iterator(); iter.hasNext();){
Object value = iter.next();
System.out.println(value);
}
}
}
class M {
int age;
public M(int age)
{
this.age = age;
}
public String toString()
{
return "M[age:" + age + "]";
}
}
输出:
[M[age:9], M[age:5], M[age:-3]]
M[age:9]
M[age:5]
M[age:-3]
三、导航集
导航集是一个有序集,允许您使用其子集在各种方式。
NavigableSet
表示Java集合中的可导航集合框架。NavigableSet
接口继承了SortedSet
接口和扩展SortedSet
。NavigableSet
界面可以以相反的顺序导航集合与SortedSet
中定义的顺序相比。- headSet(), tailSet()和 subSet()从 NavigableSet 接口接受布尔标志以将元素包括在子集边界的开始或结束处。
- lower()方法返回小于指定元素的最大元素。
- floor()方法返回 NavigableSet 中小于或等于指定元素的最大元素。
- higher()方法返回最小元素大于指定元素的 NavigableSet 。
- ceiling()方法返回 NavigableSet 中大于或等于指定元素的最小元素。
- pollFirst()和 pollLast()分别检索和删除 NavigableSet 的第一个和最后一个元素。 如果NavigableSet为空,它们返回null。
TreeSet 类是 NavigableSet 接口的实现类之一。我们可以使用 TreeSet 作为集合,排序集合和可导航集合。
例子
public class Main {
public static void main(String[] args) {
NavigableSet<Integer> ns = new TreeSet<>();
ns.add(0);
ns.add(1);
ns.add(2);
ns.add(3);
ns.add(4);
ns.add(5);
ns.add(6);
// Get a reverse view of the navigable set
NavigableSet<Integer> reverseNs = ns.descendingSet();
// Print the normal and reverse views
System.out.println("Normal order: " + ns);
System.out.println("Reverse order: " + reverseNs);
NavigableSet<Integer> threeOrMore = ns.tailSet(3, true);
System.out.println("3 or more: " + threeOrMore);
System.out.println("lower(3): " + ns.lower(3));
System.out.println("floor(3): " + ns.floor(3));
System.out.println("higher(3): " + ns.higher(3));
System.out.println("ceiling(3): " + ns.ceiling(3));
System.out.println("pollFirst(): " + ns.pollFirst());
System.out.println("Navigable Set: " + ns);
System.out.println("pollLast(): " + ns.pollLast());
System.out.println("Navigable Set: " + ns);
System.out.println("pollFirst(): " + ns.pollFirst());
System.out.println("Navigable Set: " + ns);
System.out.println("pollFirst(): " + ns.pollFirst());
System.out.println("Navigable Set: " + ns);
System.out.println("pollFirst(): " + ns.pollFirst());
System.out.println("Navigable Set: " + ns);
System.out.println("pollFirst(): " + ns.pollFirst());
System.out.println("pollLast(): " + ns.pollLast());
}
}
输出
Normal order:[0,1,2,3,4,5,6]
Reverse order:[6,5,4,3,2,1,0]
3 or more:[3,4,5,6]
lower(3):2
floor(3):3
higher(3):4
ceiling(3):3
pollFirst():0
Navigable Set:[1,2,3,4,5,6]
pollLast():6