热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java集合框架深入解析:HashSet详解

本文详细介绍了HashSet类,它是Set接口的一个实现,底层使用哈希表(实际上是HashMap实例)。HashSet不保证元素的迭代顺序,并且是非线程安全的。

HashSet概述

HashSet是Java集合框架中的一个重要类,实现了Set接口。它内部使用哈希表(实际上是HashMap实例)来存储元素。HashSet不保证元素的迭代顺序,这意味着每次迭代的结果可能不同。此外,HashSet是非线程安全的,如果需要线程安全的Set,可以使用Collections.synchronizedSet方法进行包装:

Set s = Collections.synchronizedSet(new HashSet(...));

HashSet的特点

1. HashSet不维护任何顺序,元素将以随机顺序返回。

2. HashSet不允许有重复元素,如果尝试添加重复元素,添加操作将被忽略。

3. HashSet允许有一个null值,但多次插入null值只会保留一个。

4. HashSet是非线程安全的。

5. HashSet返回的迭代器是快速失败的,即在创建迭代器后修改HashSet会导致迭代器抛出ConcurrentModificationException异常,除非通过迭代器的remove方法进行修改。

HashSet的常用操作

1. 基本示例

package com.example.collection;

import java.util.HashSet;

public class HashSetExample {
    public static void main(String[] args) {
        // 创建HashSet
        HashSet hset = new HashSet<>();
        
        // 添加元素
        hset.add("Apple");
        hset.add("Mango");
        hset.add("Grapes");
        hset.add("Orange");
        hset.add("Fig");
        
        // 尝试添加重复元素
        hset.add("Apple");
        hset.add("Mango");
        
        // 尝试添加null值
        hset.add(null);
        hset.add(null);
        
        // 显示HashSet元素
        System.out.println(hset);
    }
}

输出:
[null, Apple, Grapes, Fig, Mango, Orange]

2. 删除所有元素

package com.example.collection;

import java.util.HashSet;

public class EmptyHashSetExample {
    public static void main(String[] args) {
        // 创建HashSet
        HashSet hset = new HashSet<>();
        
        // 添加元素
        hset.add("Element1");
        hset.add("Element2");
        hset.add("Element3");
        hset.add("Element4");
        hset.add("Element5");
        
        // 显示HashSet元素
        System.out.println("Before: HashSet contains: " + hset);
        
        // 清空HashSet
        hset.clear();
        
        // 再次显示HashSet元素
        System.out.println("After: HashSet contains: " + hset);
    }
}

输出:
Before: HashSet contains: [Element5, Element4, Element3, Element2, Element1]
After: HashSet contains: []

3. 迭代元素

3.1 使用Iterator

3.2 使用for-each循环

package com.example.collection;

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

public class IterateHashSet {
    public static void main(String[] args) {
        // 创建HashSet
        HashSet hset = new HashSet<>();
        
        // 添加元素
        hset.add("Chaitanya");
        hset.add("Rahul");
        hset.add("Tim");
        hset.add("Rick");
        hset.add("Harry");
        
        // 使用Iterator迭代
        System.out.println("----使用Iterator:");
        Iterator it = hset.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        
        // 使用for-each循环迭代
        System.out.println("----使用for-each循环:");
        for (String temp : hset) {
            System.out.println(temp);
        }
    }
}

输出:
----使用Iterator:
Chaitanya
Rahul
Harry
Tim
Rick
----使用for-each循环:
Chaitanya
Rahul
Harry
Tim
Rick

4. 转换为数组

package com.example.collection;

import java.util.HashSet;

public class ConvertHashSetToArray {
    public static void main(String[] args) {
        // 创建HashSet
        HashSet hset = new HashSet<>();
        
        // 添加元素
        hset.add("Element1");
        hset.add("Element2");
        hset.add("Element3");
        hset.add("Element4");
        
        // 显示HashSet元素
        System.out.println("HashSet contains: " + hset);
        
        // 转换为数组
        String[] array = new String[hset.size()];
        hset.toArray(array);
        
        // 显示数组元素
        System.out.println("Array elements:");
        for (String temp : array) {
            System.out.println(temp);
        }
    }
}

输出:
HashSet contains: [Element4, Element3, Element2, Element1]
Array elements:
Element4
Element3
Element2
Element1

5. 转换为TreeSet

package com.example.collection;

import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

public class ConvertHashSetToTreeSet {
    public static void main(String[] args) {
        // 创建HashSet
        HashSet hset = new HashSet<>();
        
        // 添加元素
        hset.add("Element1");
        hset.add("Element2");
        hset.add("Element3");
        hset.add("Element4");
        
        // 显示HashSet元素
        System.out.println("HashSet contains: " + hset);
        
        // 转换为TreeSet
        Set tset = new TreeSet<>(hset);
        
        // 显示TreeSet元素
        System.out.println("TreeSet contains:");
        for (String temp : tset) {
            System.out.println(temp);
        }
    }
}

输出:
HashSet contains: [Element4, Element3, Element2, Element1]
TreeSet contains:
Element1
Element2
Element3
Element4

6. 转换为List/ArrayList

package com.example.collection;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class ConvertHashSetToList {
    public static void main(String[] args) {
        // 创建HashSet
        HashSet hset = new HashSet<>();
        
        // 添加元素
        hset.add("Steve");
        hset.add("Matt");
        hset.add("Govinda");
        hset.add("John");
        hset.add("Tommy");
        
        // 显示HashSet元素
        System.out.println("HashSet contains: " + hset);
        
        // 转换为ArrayList
        List list = new ArrayList<>(hset);
        
        // 显示ArrayList元素
        System.out.println("ArrayList contains: " + list);
    }
}

输出:
HashSet contains: [Matt, Steve, Govinda, John, Tommy]
ArrayList contains: [Matt, Steve, Govinda, John, Tommy]

HashSet与HashMap的比较

相同点

1. 两者都是非线程安全的。

2. 都不保证元素的顺序。

3. 从源码角度来看,HashSet内部使用HashMap来实现其操作。

4. 在添加、删除元素等操作时,两者的性能表现一致。

不同点

HashSetHashMap
实现的是Set接口实现的是Map接口
存储的是单个对象(元素或值),例如:[null, Apple, Grapes, Fig, Mango, Orange]存储的是键值对(Key-Value)
不允许有重复值不允许有重复键,但可以有多个重复值
只允许有一个null元素允许有一个null键,多个null值

推荐阅读
author-avatar
虎爷在江湖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有