无序的
,不能包含重复的对象
Set 实现了 Collection 接口,它主要有两个常用的实现类:HashSet 类和 TreeSet类。
HashSet 是 Set 接口的典型实现
,大多数时候使用 Set 集合时就是使用这个实现类。HashSet 是按照 Hash 算法来存储集合中的元素。因此具有很好的存取和查找性能
。
HashSet 具有以下特点:
在 HashSet 类中实现了 Collection 接口中的所有方法。HashSet 类的常用构造方法重载形式如下。
下面的代码演示了创建两种不同形式的 HashSet 对象。
HashSet hs = new HashSet(); // 调用无参的构造函数创建HashSet对象
HashSet<String> hss = new HashSet<String>(); // 创建泛型的 HashSet 集合对象
例 1
编写一个 Java 程序,使用 HashSet 创建一个 Set 集合,并向该集合中添加 4 套食物。具体实现代码如下:
import java.util.HashSet;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
HashSet<String> courseSet=new HashSet<String>();//创建一个空的Set集合
String course1 = new String("薯片");
String course2 = new String("炸鸡");
String course3 = new String("汉堡");
String course4 = new String("鸡肉卷");
courseSet.add(course1); // 将 course1 存储到 Set 集合中
courseSet.add(course2); // 将 course2 存储到 Set 集合中
courseSet.add(course3); // 将 course3 存储到 Set 集合中
courseSet.add(course4); // 将 course4 存储到 Set 集合中
System.out.println("肥宅快乐店");
Iterator<String> it=courseSet.iterator();
while(it.hasNext()){
System.out.print(it.next()+" ");
}
System.out.println();
System.out.print("有"+courseSet.size()+"个吃的");
}
}
首先使用 HashSet 类的构造方法创建了一个 Set 集合,接着创建了 4 个 String 类型的对象,并将这些对象存储到 Set 集合中。使用 HashSet 类中的 iterator() 方法获取一个 Iterator 对象,并调用其 hasNext() 方法遍历集合元素,再将使用 next() 方法读取的元素强制转换为 String 类型。最后调用 HashSet 类中的 size() 方法获取集合元素个数。
运行该程序,输出的结果如下:
肥宅快乐店
汉堡 炸鸡 薯片 鸡肉卷
有4个吃的
注意:在以上示例中,如果再向 CourseSet 集合中再添加一个名称为“Java入门教程”的 String 对象,则输出的结果与上述执行结果相同。也就是说,如果向 Set 集合中添加两个相同的元素,则后添加的会覆盖前面添加的元素,即在 Set 集合中不会出现相同的元素。
TreeSet 类同时实现了 Set 接口
和 SortedSet 接口
。
SortedSet 接口
是 Set 接口的子接口,可以实现对集合进行自然排序
,因此使用 TreeSet 类实现的 Set 接口默认情况下是自然排序的,这里的自然排序指的是升序排序。
TreeSet 只能对实现了 Comparable 接口的类对象进行排序
,因为 Comparable 接口中有一个compareTo(Object o) 方法用于比较两个对象的大小。例如 a.compareTo(b),如果 a 和 b相等,则该方法返回 0;如果 a 大于 b,则该方法返回大于 0 的值;如果 a 小于 b,则该方法返回小于 0 的值。
表 1 列举了 JDK 类库中实现 Comparable 接口的类,以及这些类对象的比较方式。
表 1 实现Comparable接口类对象的比较方式:
类 | 比较方式 |
---|---|
包装类(BigDecimal、Biglnteger、 Byte、Double、Float、Integer、Long 及 Short) | 按数字大小比较 |
Character | 按字符的 Unicode 值的数字大小比较 |
String | 按字符串中字符的 Unicode 值的数字大小比较 |
TreeSet 类除了实现 Collection 接口的所有方法之外,还提供了如表 2 所示的方法。
表 2 TreeSet类的常用方法:
方法名称 | 说明 |
---|---|
E first() | 返回此集合中的第一个元素。其中,E 表示集合中元素的数据类型 |
E last() | 返回此集合中的最后一个元素 |
E poolFirst() | 获取并移除此集合中的第一个元素 |
E poolLast() | 获取并移除此集合中的最后一个元素 |
SortedSet |
返回一个新的集合,新集合包含原集合中 fromElement 对象与 toElement对象之间的所有对象。包含 fromElement 对象,不包含 toElement 对象 |
SortedSet |
返回一个新的集合,新集合包含原集合中 toElement 对象之前的所有对象。不包含 toElement 对象 |
SortedSet |
返回一个新的集合,新集合包含原集合中 fromElement 对象之后的所有对象。包含 fromElement 对象 |
注意:表面上看起来这些方法很多,其实很简单。因为 TreeSet 中的元素是有序的,所以增加了访问第一个、前一个、后一个、最后一个元素的方法,并提供了 3 个从 TreeSet 中截取子 TreeSet 的方法。
例1
import java.util.Iterator;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
TreeSet<Integer> t=new TreeSet<Integer>();
t.add(1);
t.add(23);
t.add(209);
t.add(3);
for(int i=0;i<t.toArray().length;i++){
System.out.println(t.toArray()[i]);
}
}
}
1 3 23 209
例 2
本次有 5 名学生参加考试,当老师录入每名学生的成绩后,程序将按照从低到高的排列顺序显示学生成绩。此外,老师可以查询本次考试是否有满分的学生存在,不及格的成绩有哪些,90 分以上成绩的学生有几名。
下面使用 TreeSet 类来创建 Set 集合,完成学生成绩查询功能。具体的代码如下:
import java.util.Iterator;
import java.util.Scanner;
import java.util.SortedSet;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
TreeSet<Double> scores=new TreeSet<Double>();//创建TreeSet集合
Scanner input=new Scanner(System.in);
System.out.println("——学生成绩管理系统——");
for(int i=0;i<5;i++){
System.out.println("第"+(i+1)+"个学生成绩");
double score=input.nextDouble();
//将学生成绩转换为Double类型,添加到TreeSet集合中
scores.add(Double.valueOf(score));
}
Iterator<Double> it=scores.iterator();//创建Iterator对象
System.out.println("学生成绩从低到高的排序为:");
while(it.hasNext()){
System.out.print(it.next()+" ");
}
System.out.println("\n请输入要查询的成绩:");
double searchScore=input.nextDouble();
//contains()方法用于判断集合中包不包含某个元素,返回值是boolean。
if(scores.contains(searchScore)){
System.out.println("成绩为"+searchScore+"的学生存在");
}else{
System.out.println("成绩为"+searchScore+"的学生不存在");
}
//查询不及格的学生成绩
SortedSet<Double> score1=scores.headSet(60.0);
System.out.println("\n不及格的成绩有:");
for(int i=0;i<score1.toArray().length;i++){
System.out.print(score1.toArray()[i]+"\t");
}
//查询90分以上的学生成绩
SortedSet<Double> score2=scores.tailSet(90.0);
System.out.println("\n90分以上的成绩有");
//toArray()的方法,把List转化为数组
for(int i=0;i<score2.toArray().length;i++){
System.out.print(score2.toArray()[i]+"\t");
}
}
}
首先创建一个 TreeSet 集合对象 scores,并向该集合中添加 5 个 Double 对象。
接着使用 while 循环遍历 scores 集合对象,输出该对象中的元素,然后调用 TreeSet 类中的 contains() 方法获取该集合中是否存在指定的元素。
最后分别调用 TreeSet 类中的 headSet() 方法和 tailSet() 方法获取不及格的成绩和 90 分以上的成绩。
运行该程序,执行结果如下所示:
——学生成绩管理系统——
第1个学生成绩
67
第2个学生成绩
70
第3个学生成绩
88
第4个学生成绩
56
第5个学生成绩
98
学生成绩从低到高的排序为:
56.0 67.0 70.0 88.0 98.0
请输入要查询的成绩:
98
成绩为98.0的学生存在
不及格的成绩有:
56.0
90分以上的成绩有
98.0
注意:在使用自然排序时只能向 TreeSet 集合中添加相同数据类型的对象
,否则会抛出 ClassCastException 异常
。如果向 TreeSet 集合中添加了一个 Double 类型的对象,则后面只能添加 Double 对象,不能再添加其他类型的对象,例如 String 对象等。