Java中的Set集合是一种不允许重复元素的集合。它是基于哈希表实现的,具有快速的插入、删除和查找操作。
常见的Set集合类有HashSet、LinkedHashSet和TreeSet。
Set集合提供了常见的集合操作,如添加元素、删除元素、判断元素是否存在等。它还提供了迭代器来遍历集合中的元素。
1.HashSet集合
HashSet是最常用的Set集合类,它不保证元素的顺序,内部使用哈希表来存储元素。HashSet的元素是无序的,不允许重复元素。
以下是使用HashSet集合的示例代码:
import java.util.HashSet;
import java.util.Set;
public class SetExample {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
// 添加元素
set.add("apple");
set.add("banana");
set.add("orange");
// 删除元素
set.remove("banana");
// 判断元素是否存在
boolean contains = set.contains("apple");
System.out.println("Contains apple: " + contains);
// 遍历集合
for (String element : set) {
System.out.println(element);
}
}
}
输出结果为:
Contains apple: true
orange
apple
以上代码演示了如何使用HashSet集合来添加、删除、判断元素以及遍历集合中的元素。
实例:元素去重操作
package Demo14_Set;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
上面的代码是一个名为"Student"的类,它重写了toString()、equals()和hashCode()方法。
- toString()方法返回一个包含学生姓名和年龄的字符串表示。
- equals()方法用于比较两个学生对象是否相等。它首先判断两个对象的引用是否相等,如果相等则直接返回true。然后判断两个对象的类是否相同,如果不同则返回false。最后比较两个对象的姓名和年龄是否相等,使用Objects.equals()方法进行比较。
- hashCode()方法返回一个根据姓名和年龄计算出的哈希码。它使用Objects.hash()方法根据姓名和年龄生成哈希码。
这些方法的重写是为了在Set集合中进行元素的比较和查找。在使用Set集合时,如果需要判断两个对象是否相等,就会使用equals()方法,而在插入元素和查找元素时,会使用hashCode()方法来确定元素在集合中的位置。
在上面的示例代码中,如果要在HashSet或LinkedHashSet中存储Student对象,就需要重写equals()和hashCode()方法,以确保正确的比较和查找行为。
去重的操作方法是重写的equals和hashCode方法,idea中的操作操作方法如下
1.alt+insert键,调出Generate窗口,并点击equals() and hashCode()
2.接着一路enter
idea帮我们生成如下代码块
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
主方法中
import java.util.HashSet;
public class StuTest {
public static void main(String[] args) {
HashSet<Student> stuSet = new HashSet<>();
stuSet.add(new Student("JJ",12));
stuSet.add(new Student("kk",15));
stuSet.add(new Student("gg",10));
stuSet.add(new Student("JJ",12));
stuSet.add(new Student("pp",16));
for (Student stu : stuSet) {
System.out.println(stu);
}
}
}
运行结果 ,两个名JJ年龄12的元素被去除了
2.TreeSet集合
TreeSet是基于红黑树实现的,它可以对元素进行排序。TreeSet的元素是有序的,不允许重复元素。
实例:双色球选取
import java.util.Random;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
Random ran = new Random();
int blueBall = ran.nextInt(16)+1;
TreeSet<Integer> redBall = new TreeSet<>();
while (redBall.size()<6){
redBall.add(ran.nextInt(33)+1);
}
System.out.println("红球:"+redBall+"|蓝球:["+blueBall+"]");
}
}
首先创建一个Random对象ran,用于生成随机数。然后使用ran.nextInt(16)+1来生成一个1到16之间的随机数,表示蓝球,将其赋值给变量blueBall。
接下来创建一个TreeSet集合redBall,用于存储红球的选号。通过一个while循环,不断生成随机数,并使用redBall.add()方法将其加入集合中,直到集合大小达到6个。
最后,使用System.out.println()输出选号结果,红球部分通过redBall.toString()得到红球集合的字符串表示,蓝球通过blueBall直接输出。
TreeSet是一个有序的集合,它会根据元素的自然顺序进行排序。在上面的代码中,红球集合redBall会自动按照升序排序。
3.LinkedHashSet集合
LinkedHashSet继承自HashSet,它保持了元素的插入顺序。内部使用链表来维护元素的顺序,同时使用哈希表来实现快速的查找操作。
LinkedHashSet<String> set = new LinkedHashSet<>(); //读写有序
set.add("A");
set.add("B");
set.add("C");
set.add("D");
System.out.println(set);
4.自然排序
1.默认排序规则
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
int res = this.getAge() - o.getAge();
return 0 == res?this.getName().compareTo(o.getName()):res;
}
}
对于自定义类,可以通过实现Comparable接口来定义自然排序规则。实现Comparable接口的类需要重写compareTo()方法,根据类的特定属性进行比较和排序。
这段代码是在Student类中实现了Comparable接口,并重写了compareTo()方法。在compareTo()方法中,首先比较了两个Student对象的年龄(age)属性,通过减法得到差值res。如果差值为0,即年龄相同,那么就比较姓名(name)属性的字典顺序,使用compareTo()方法返回结果。如果差值不为0,说明年龄不同,直接返回差值res。
这样实现Comparable接口和重写compareTo()方法后,就可以使用Java的排序方法(例如Collections.sort()或Arrays.sort())对Student对象进行排序。排序时会根据compareTo()方法的返回值来确定元素的顺序。如果返回值小于0,则当前对象排在前面;如果返回值大于0,则当前对象排在后面;如果返回值等于0,则两个对象相等,顺序不变。
主方法
import java.util.Comparator;
import java.util.TreeSet;
public class StuTest {
public static void main(String[] args) {
TreeSet<Student> stuSet = new TreeSet<>();//默认排序规则
stuSet.add(new Student("JJ",12));
stuSet.add(new Student("kk",15));
stuSet.add(new Student("gg",10));
stuSet.add(new Student("oo",12));
stuSet.add(new Student("pp",16));
for (Student stu : stuSet) {
System.out.println(stu);
}
}
}
2.自定义排序规则
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
import java.util.Comparator;
import java.util.TreeSet;
public class StuTest {
public static void main(String[] args) {
TreeSet<Student> stuSet = new TreeSet<>(new Comparator<Student>() {//自定义排序规则(匿名内部类方法实现)
@Override
public int compare(Student o1, Student o2) {
int res = o1.getAge() - o2.getAge();
return 0 == res ? o1.getName().compareTo(o2.getName()) : res;
}
});
stuSet.add(new Student("JJ",12));
stuSet.add(new Student("kk",15));
stuSet.add(new Student("gg",10));
stuSet.add(new Student("oo",12));
stuSet.add(new Student("pp",16));
for (Student stu : stuSet) {
System.out.println(stu);
}
}
}
这段代码创建了一个TreeSet集合,集合中的元素是Student对象。在创建TreeSet时使用了一个Comparator匿名内部类来定义自定义的排序规则。
在Comparator的compare()方法中,首先比较了两个Student对象的年龄(age)属性,通过减法得到差值res。如果差值为0,即年龄相同,那么就比较姓名(name)属性的字典顺序,使用compareTo()方法返回结果。如果差值不为0,说明年龄不同,直接返回差值res。
这样通过自定义的Comparator来指定排序规则,可以在TreeSet中按照指定的规则对元素进行排序。在集合中插入元素时,会根据Comparator的compare()方法返回的结果来确定元素的顺序。如果返回值小于0,则当前对象排在前面;如果返回值大于0,则当前对象排在后面;如果返回值等于0,则两个对象相等,顺序不变。