HashSet知识总结:高效无序集合

目录

1 简介 

2 基本操作 

2.1 添加元素

2.2 删除元素

2.3 判断元素是否存在 

2.4 获取集合大小

2.5 遍历 HashSet  

使用迭代器遍历

使用增强型 for 循环遍历 

2.6  自定义对象存储 

3 性能考虑 

1. 添加元素的性能

2. 查询元素的性能

3. 删除元素的性能

4 完整的示例代码

5 总结  


1 简介 

  • 定义:HashSet是一种基于哈希表实现的Set接口集合类型,它不允许存储重复元素。
  • HashSet的特点:
  • 不保证元素的顺序(实际上,由于哈希算法的原因,元素的顺序可能会随着集合的增长而变化)。
  • 允许存储一个null元素。
  • 操作效率高,大多数操作(如添加、删除、包含检查等)平均时间复杂度为O(1)。

2 基本操作 

2.1 添加元素

要向 HashSet 中添加元素,可以使用 add() 方法:

import java.util.HashSet;

public class HashSetExample {
    public static void main(String[] args) {
        // 创建一个HashSet实例
        HashSet hashSet = new HashSet<>();

        // 添加元素
        hashSet.add("Apple");
        hashSet.add("Banana");
        hashSet.add("Cherry");

        // 尝试添加重复元素(不会生效)
        hashSet.add("Apple");

        // 打印HashSet内容
        System.out.println("HashSet after adding elements: " + hashSet);
    }
}

2.2 删除元素

要从 HashSet 中删除元素,可以使用 remove() 方法: 

import java.util.HashSet;

public class HashSetExample {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet<>();
        hashSet.add("Apple");
        hashSet.add("Banana");
        hashSet.add("Cherry");

        // 删除元素
        hashSet.remove("Banana");

        // 打印删除后的HashSet
        System.out.println("HashSet after removing 'Banana': " + hashSet);
    }
}

2.3 判断元素是否存在 

可以使用 contains() 方法来检查元素是否存在于 HashSet 中: 

Set animals = new HashSet<>(Arrays.asList("狗", "猫", "鸟"));
boolean containsCat = animals.contains("猫");

上述代码检查了 “猫” 是否存在于 HashSet 中,并将结果存储在 containsCat 变量中。 

2.4 获取集合大小

要获取 HashSet 中元素的数量,可以使用 size() 方法: 

 int size = hashSet.size();

上述代码获取了集合中元素的数量,并将结果存储在 size 变量中。 

2.5 遍历 HashSet  

遍历 HashSet 中的元素可以使用迭代器或增强型 for 循环。以下是两种遍历方式的示例: 

使用迭代器遍历

import java.util.HashSet;
import java.util.Iterator;

public class HashSetExample {

    public static void main(String[] args) {
        // 初始化一个HashSet并添加元素
        HashSet hashSet = new HashSet<>();
        hashSet.add("Apple");
        hashSet.add("Banana");
        hashSet.add("Cherry");

        // 使用迭代器遍历HashSet
        System.out.println("Traversing HashSet using Iterator:");
        Iterator iterator = hashSet.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);
        }
    }
}

使用增强型 for 循环遍历 

import java.util.HashSet;

public class HashSetExample {

    public static void main(String[] args) {
        // 初始化一个HashSet并添加元素
        HashSet hashSet = new HashSet<>();
        hashSet.add("Apple");
        hashSet.add("Banana");
        hashSet.add("Cherry");

        // 使用增强型for循环遍历HashSet
        System.out.println("Traversing HashSet using Enhanced For Loop:");
        for (String element : hashSet) {
            System.out.println(element);
        }
    }
}

2.6  自定义对象存储 

如果存储的是自定义对象,需要正确实现 hashCode()equals() 方法。 

import java.util.HashSet;
import java.util.Objects;

// 自定义类 Person,包含 name 和 age 属性
class Person {
    String name; // 姓名
    int age;     // 年龄

    // 构造方法,用于初始化对象
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 重写 hashCode 方法,确保根据 name 和 age 生成唯一的哈希值
    @Override
    public int hashCode() {
        return Objects.hash(name, age); // 使用 Objects.hash() 生成更健壮的哈希值
    }

    // 重写 equals 方法,判断两个 Person 对象是否相等
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true; // 如果两个引用指向同一个对象,则直接返回 true
        if (obj == null || getClass() != obj.getClass()) return false; // 检查是否为 null 或类型不匹配
        Person person = (Person) obj; // 将 obj 转换为 Person 类型
        return age == person.age && Objects.equals(name, person.name); // 比较 name 和 age 是否相同
    }

    // 重写 toString 方法,方便打印对象时显示有意义的信息
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

public class CustomObjectHashSetExample {
    public static void main(String[] args) {
        // 创建一个 HashSet,用于存储自定义对象 Person
        HashSet people = new HashSet<>();

        // 向集合中添加三个 Person 对象
        people.add(new Person("Alice", 30)); // 添加 Alice,年龄 30
        people.add(new Person("Bob", 25));   // 添加 Bob,年龄 25
        people.add(new Person("Alice", 30)); // 再次添加 Alice,年龄 30(重复元素)

        // 打印提示信息
        System.out.println("HashSet with custom objects:");

        // 遍历 HashSet 并逐行打印每个 Person 对象
        for (Person person : people) {
            System.out.println(person);
        }
    }
}

3 性能考虑 

 HashSet 的性能通常是很高的,它提供了快速的插入、删除和查询操作。但需要注意以下几点:

1. 添加元素的性能

  • 高效性:通常情况下,HashSet 的添加操作非常快,时间复杂度为 O(1)
  • 负载因子:当负载因子接近默认值 0.75 时,HashSet 会自动扩容,这可能导致性能暂时下降。
  • 优化:可以通过预先设置合适的初始容量和负载因子来减少扩容操作。

2. 查询元素的性能

  • 高效性:查询操作基于哈希表实现,时间复杂度为 O(1)
  • 哈希冲突:在有哈希冲突的情况下,查询操作的时间复杂度可能会增加至 O(n)

3. 删除元素的性能

  • 高效性:删除操作的时间复杂度通常为 O(1)
  • 定位元素:类似于查询操作,删除前需要先定位元素。
  • 哈希冲突:如果存在哈希冲突,删除操作的时间复杂度可能会增加至 O(n)

4 完整的示例代码

import java.util.HashSet;
import java.util.Iterator;

public class HashSetExample {

    public static void main(String[] args) {
        // 创建一个 HashSet 集合
        HashSet hashSet = new HashSet<>();

        // 向集合中添加元素
        hashSet.add("苹果"); // 添加元素
        hashSet.add("香蕉");
        hashSet.add("樱桃");

        // 尝试添加重复元素,不会生效
        hashSet.add("苹果"); // 不会重复添加,因为 HashSet 不允许重复元素

        // 打印集合内容
        System.out.println("HashSet 的内容: " + hashSet);

        // 获取集合大小
        System.out.println("集合的大小为: " + hashSet.size());

        // 检查是否包含某个元素
        if (hashSet.contains("香蕉")) {
            System.out.println("集合中包含元素: 香蕉");
        } else {
            System.out.println("集合中不包含元素: 香蕉");
        }

        // 删除元素
        hashSet.remove("樱桃"); // 删除指定元素
        System.out.println("删除'樱桃'后的集合内容: " + hashSet);

        // 遍历集合(增强型 for 循环)
        System.out.println("使用增强型 for 循环遍历集合:");
        for (String element : hashSet) {
            System.out.println(element);
        }

        // 遍历集合(使用迭代器)
        System.out.println("使用迭代器遍历集合:");
        Iterator iterator = hashSet.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        // 清空集合
        hashSet.clear(); // 清空所有元素
        System.out.println("清空后的集合是否为空: " + hashSet.isEmpty());
    }
}

5 总结  

本文探讨了 Java 中的 HashSet 集合,涵盖了其核心概念、创建与初始化方法、基础操作流程、多种遍历手段、性能考量及使用时的注意事项,并提供了相应的示例代码。作为一款广泛使用的集合类,HashSet 专门用于存储独一无二的元素,适合于众多应用场景。掌握 HashSet 的正确用法能够显著提升您的 Java 应用程序的效能与可维护性。期待本文能为您的学习和理解 HashSet 提供有价值的指导和帮助。 

你可能感兴趣的:(数据结构,java,数据结构)