1、HashSet:
HashSet 集合保证元素唯一性的原理
1.根据对象的哈希值计算存储位置
如果当前位置没有元素则直接存入
如果当前位置有元素存在,则进入第二步
2.当前元素的元素和已经存在的元素比较哈希值
如果哈希值不同,则将当前元素进行存储
如果哈希值相同,则进入第三步
3.通过equals()方法比较两个元素的内容
如果内容不相同,则将当前元素进行存储
如果内容相同,则不存储当前元素
测试代码1;
package settest.com;
import java.util.HashSet;
import java.util.Iterator;
public class HashSetExample {
public static void main(String[] args) {
// 创建HashSet 实例
HashSet<String> hashSet = new HashSet<>();
// 向 HashSet 中添加元素
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Cherry");
hashSet.add("Date");
// 尝试添加重复元素,HashSet 会忽略它
hashSet.add("Apple");
// 使用增强型 for 循环遍历 HashSet
System.out.println("HashSet 中的元素(使用增强型 for 循环):");
for (String fruit : hashSet) {
System.out.println(fruit);
}
// 使用 Iterator 遍历 HashSet
System.out.println("\nHashSet 中的元素(使用 Iterator):");
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 检查 HashSet 是否包含某个元素
if (hashSet.contains("Banana")) {
System.out.println("\nHashSet 包含 Banana");
}
// 移除 HashSet 中的元素
hashSet.remove("Cherry");
System.out.println("\n移除 Cherry 后,HashSet 中的元素:");
for (String fruit : hashSet) {
System.out.println(fruit);
}
// 获取 HashSet 的大小
System.out.println("\nHashSet 的大小: " + hashSet.size());
}
}
运行结果如下:
测试代码2:
package settest.com;
import java.util.Objects;
//重写hashCode()方法时,应该始终确保:
//一致性:对于任何给定的对象,在Java应用程序执行期间,只要对象的equals比较中所用的信息没有被修改,
//那么对该对象调用hashCode()方法多次,必须一致地返回同一个整数。
//equals一致性:如果两个对象根据equals(Object obj)方法是相等的,
//那么调用这两个对象中任一对象的hashCode()方法都必须产生相同的整数结果。
//不同对象的哈希码可以相同(不是强制的,只是哈希碰撞的可能性)。
public class HashCode {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
// 打印str1的哈希值
System.out.println("str1的哈希值: " + str1.hashCode());
// 打印str2的哈希值
System.out.println("str2的哈希值: " + str2.hashCode());
// 自定义对象的哈希值
MyObject obj1 = new MyObject("example");
MyObject obj2 = new MyObject("example");
// 打印obj1的哈希值
System.out.println("obj1的哈希值: " + obj1.hashCode());
// 默认情况下,不同对象的哈希值不同,但可以通过重写hashCode()改变。
System.out.println("obj2的哈希值: " + obj2.hashCode());
}
}
class MyObject {
private String name;
public MyObject(String name) {
this.name = name;
}
// 重写hashCode()方法以基于对象的某个字段计算哈希值
@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}
// 重写equals()方法以保持hashCode()和equals()的一致性
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
MyObject myObject = (MyObject) obj;
return Objects.equals(name, myObject.name);
}
}
运行结果如下:
2、LinkedHashSet:
测试代码:
package settest.com;
import java.util.LinkedHashSet;
import java.util.Set;
public class LinkedHashSetDemo {
public static void main(String[] args) {
// 创建LinkedHashSet实例
Set<String> linkedHashSet = new LinkedHashSet<>();
// 向LinkedHashSet中添加元素
linkedHashSet.add("Apple");
linkedHashSet.add("Banana");
linkedHashSet.add("Cherry");
// 尝试添加重复元素
linkedHashSet.add("Banana"); // 不会添加,因为"Banana"已经存在
// 遍历LinkedHashSet,有序性
System.out.println("LinkedHashSet elements (in insertion order):");
for (String fruit : linkedHashSet) {
System.out.println(fruit);
}
// 删除一个元素
linkedHashSet.remove("Cherry");
// 再次遍历LinkedHashSet,删除后的结果
System.out.println("\nLinkedHashSet after removing 'Cherry':");
for (String fruit : linkedHashSet) {
System.out.println(fruit);
}
// 添加更多元素,维护插入顺序
linkedHashSet.add("Date");
linkedHashSet.add("Avocado");
// 遍历最终结果
System.out.println("\nLinkedHashSet after adding more elements:");
for (String fruit : linkedHashSet) {
System.out.println(fruit);
}
}
}
运行结果如下:
3、 TreeSet:
测试代码:
package settest.com;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
// 创建TreeSet实例存储Flower对象
TreeSet<Flower> flowerSet = new TreeSet<>();
// 向TreeSet中添加元素
flowerSet.add(new Flower("Rose"));
flowerSet.add(new Flower("Lily"));
flowerSet.add(new Flower("Daisy"));
// 添加重复元素(按名称)
flowerSet.add(new Flower("Rose")); // 不会添加,因为已经存在名称为Rose的Flower
// 遍历TreeSet,有序性
System.out.println("TreeSet elements (sorted by name):");
for (Flower flower : flowerSet) {
System.out.println(flower);
}
// 查找元素(查找第一个元素)
Flower firstFlower = flowerSet.first();
System.out.println("\nFirst element in TreeSet: " + firstFlower);
// 删除元素
flowerSet.remove(new Flower("Daisy"));
// 再次遍历TreeSet,删除后的结果
System.out.println("\nTreeSet after removing Daisy:");
for (Flower flower : flowerSet) {
System.out.println(flower);
}
// 添加更多元素
flowerSet.add(new Flower("Tulip"));
//范围查找需要根据具体需求实现逻辑,比如使用tailSet()或headSet()
System.out.println("\nFull TreeSet after adding Tulip:");
for (Flower flower : flowerSet) {
System.out.println(flower);
}
// 假设要找名称大于"Lily"(字典序)的所有花,使用tailSet
System.out.println("\nFlowers with name > 'Lily' (dictionary order):");
for (Flower flower : flowerSet.tailSet(new Flower("Lily"))) {
System.out.println(flower);
}
}
}
运行结果如下:
4、Comparable的使用:
创建一个 Flower实现Comparable接口:
package settest.com;
public class Flower implements Comparable<Flower> {
private String name;
public Flower(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Flower other) {
return this.name.compareTo(other.name); // 按名称的字典序排序
}
@Override
public String toString() {
return "Flower{" +
"name='" + name + '\'' +
'}';
}
}
测试类:
package settest.com;
import java.util.TreeSet;
//自然排序Comparable的使用
//按name和color排序的Flower对象列表,其中name相同的Flower对象会进一步按color排序。
public class FlowerSetDemo {
public static void main(String[] args) {
TreeSet<Flower> flowerSet = new TreeSet<>();
flowerSet.add(new Flower("Rose", "Red"));
flowerSet.add(new Flower("Lily", "White"));
flowerSet.add(new Flower("Daisy", "Yellow"));
flowerSet.add(new Flower("Rose", "Pink")); // 会被添加,因为name相同但color不同
for (Flower flower : flowerSet) {
System.out.println(flower);
}
}
static class Flower implements Comparable<Flower> {
private String name;
private String color;
public Flower(String name, String color) {
this.name = name;
this.color = color;
}
@Override
public int compareTo(Flower other) {
int nameCompare = this.name.compareTo(other.name);
if (nameCompare != 0) {
return nameCompare;
}
return this.color.compareTo(other.color);
}
@Override
public String toString() {
return "Flower{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
'}';
}
}
}
运行结果如下: