HashSet和HashMap

简介: HashSet和HashMap

一、HashSet

951ca09bfa344ca1a8ac54e9f4771b94.png

1、HashSet简单介绍

说到HsahSet就要先说Set接口

Set 接口和List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对 Collection 接口进行功能上的扩充,只是比Collection接口更加严格。与List 接口不同的是,Set接口中的元素无序,并且都会以某种规则保证存入的元素不出现重复

Set接口主要有两个实现类,分别是 HashSet和TreeSet。其中,HashSet是根据对象的哈希值来确定元素在集合中的存储的位置,因此具有良好的存取和查找性能。TreeSer则是以二叉树的方式来存储元素,它可以实现对集合中的元素进行排序。

HashSet

HashSet是 Set接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的。当向 HashSet集合中添加一个元素时,首先会调用该元素的hashCode()方法来确定元素的存储位置,然后再调用元素对象的equals()方法来确保该位置没有重复元素

2、HashSet的常用方法

782726a58f6047f69eb27ed7d62cc2f1.png

常用方法代码演示:

import java.util.HashSet;
import java.util.Iterator;
public class Main {
    public static void main(String[] args) {
        //使用HashSet集合时先要指定泛型中具体的包装类
        HashSet<Integer> hashSet=new HashSet<>();
        //向hashSet中添加元素   add()
        hashSet.add(12);
        hashSet.add(34);
        hashSet.add(56);
        //判断hashSet中是否有12和89两个元素        contains()
        System.out.println(hashSet.contains(12));    //true
        System.out.println(hashSet.contains(89));    //false
        //hashSet中元素的个数       size()
        System.out.println(hashSet.size());          //3
        //Iterator迭代器遍历集合
        Iterator<Integer> iterator=hashSet.iterator();
        while (iterator.hasNext()){
            Integer i=iterator.next();
            System.out.println(i);                   //输出顺序与添加顺序不同
            //System.out.println(iterator.next());
        }
        //foreach遍历集合
        hashSet.forEach(o-> System.out.println(o));  //输出顺序与添加顺序不同
        //hashSet.forEach(System.out::println);
        //删除hashSet中的某个元素     remove()
        System.out.println(hashSet.remove(12));   //true     删除成功返回true
        System.out.println(hashSet.remove(89));   //false    删除失败返回false
        System.out.println(hashSet.size());          //2
        //克隆Hashset实例的浅层副本:元素本身不被克隆。
        hashSet.add(12);
        Object clone=hashSet.clone();
        System.out.println(clone);                   //输出格式为[元素1,元素2]  输出顺序与添加顺序不同 
        //删除前 判断hashSet是否为空
        System.out.println(hashSet.isEmpty());      //false
        //清空hashSet中的所以元素
        hashSet.clear();
        //删除后 判断hashSet是否为空
        System.out.println(hashSet.isEmpty());      //true
    }
}

3、HashSet保证元素不重复的原理

HashSet集合之所以能确保不出现重复的元素,是因为它在存入元素时做了很多工作。当调用 HashSet集合的add()方法存入元素时,首先调用当前存入元素的hashCode()方法获得对象的哈希值,然后根据对象的哈希值计算出一个存储位置;如果该位置上没有元素则直接将元素存入;如果该位置上有元素存在,则会调用equals()方法让当前存入的元素次和该位置上的元素进行比较。如果返回的结果为false就将该元素存入集合;返回的结果为true则说明有重复元素,就不添加到其中。若想保证输入元素与输出元素顺序保存一致,可以使用LinkedHashSet集合(与HashSet相比,使用区别并不大)



e2d71d8eef234f44aa5d0eb6b852c571.png

二、HashMap

24b54b487fb742c0b2740667151d97c8.png

1、HashMap简单介绍

HashMap集合是 Map接口的一个实现类,它用于存储键值映射关系,该集合的键和值允许为空,但键不能重复且集合中的元素是无序的HashMap底层是由哈希表结构组成的,其实就是“数组+链表”的组合体,数组是HashMap的主体结构,链表则主要是为了解决哈希值冲突而存在的分支结构。正因为这样特殊的存储结构,HashMap集合对于元素的增、删、改、查操作表现出的效率都比较高。

水平方向以数组结构为主体并在竖直方向以链表结构进行结合的就是 HashMap中的哈希表结构。在哈希表结构中,水平方向数组的长度称为HashMap集合的容量(capacity),竖直方向每个元素位置对应的链表结构称为一个桶(bucket),每个桶的位置在集合中都有对应的桶值,用于快速定位集合元素添加、查找时的位置。

HashMap 几乎等同于HashTable ,但是因为HashTable使用同步锁所以线程安全;

2、HashMet的常用方法


e8d86b8b5f054c7e89cb5391d8ebf2fb.png

常用方法代码演示:

import java.util.*;
public class Main {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap=new HashMap<>();
        //1、向hashMap中添加元素
        hashMap.put(1,"cat");
        hashMap.put(2,"tom");
        hashMap.put(3,"house");
        hashMap.put(4,"bord");
        //2、查看键对象是否存在
        System.out.println(hashMap.containsKey(1));           //true
        //3、查看是否有相应键与该值对应
        System.out.println(hashMap.containsValue("cat"));     //true
        //4、获取集合中的 键对象和值对象 集合
        System.out.println(hashMap.keySet());                 //[1, 2, 3, 4]
        System.out.println(hashMap.values());                 //[cat, tom, house, bord]
        //5、替换指定键对象映射的值
        hashMap.replace(1,"cat1");
        System.out.println(hashMap);                          //{1=cat1, 2=tom, 3=house, 4=bord}
        //6、删除指定键对象映射的键值对元素
        System.out.println(hashMap.size());                  //4
        hashMap.remove(4);
        System.out.println(hashMap);                         //{1=cat1, 2=tom, 3=house}
        System.out.println(hashMap.size());                  //3
        //7、hashMap实例的浅拷贝
        Object map=hashMap.clone();
        System.out.println(map);                            //{1=cat1, 2=tom, 3=house}
        //8、查看该key是否存在,若存在返回其value,否则返回defaultValue
        System.out.println(hashMap.getOrDefault(3,"No"));   //house
        System.out.println(hashMap.getOrDefault(4,"No"));   //No
        //9、遍历hashMap
        // 1)forEach遍历
        hashMap.forEach((key,value)-> System.out.println(key+" "+value));   //1 cat1 2 tom  3 house
        //2)Iterator迭代器遍历集合
        Set<Integer> keySet=hashMap.keySet();
        Iterator<Integer> iterator=keySet.iterator();
        while (iterator.hasNext()){
            Object key=iterator.next();
            Object value=hashMap.get(key);
            System.out.println(key+" "+value);        //1 cat1 2 tom  3 house
        }
        /*简单for循环也可以
        for (Object key : keySet) {
            Object value = hashMap.get(key);
            System.out.println(key + " " + value);
        }*/
        //8、删除hashMap中的所有映射关系,并判断是否为空
        System.out.println(hashMap.isEmpty());             //false
        hashMap.clear();
        System.out.println(hashMap.isEmpty());             //false
    }
}

3、使用LinkedHashMap集合保证元素添加顺序

import java.util.*;
public class Main {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap=new HashMap<>();
        //1、向hashMap中添加元素
        hashMap.put(2,"tom");
        hashMap.put(1,"cat");
        hashMap.put(4,"bord");
        hashMap.put(3,"house");
        System.out.println("hashmap:");
        hashMap.forEach((key,value)-> System.out.println(key+":"+value));
        LinkedHashMap<Integer,String> linkedHashMap=new LinkedHashMap<>();
        linkedHashMap.put(2,"tom");
        linkedHashMap.put(1,"cat");
        linkedHashMap.put(4,"bord");
        linkedHashMap.put(3,"house");
        System.out.println("linkedHashMap:");
        linkedHashMap.forEach((key,value)-> System.out.println(key+":"+value));
    }
}

f1b781c7270d46b3bf11da6a0c49e919.png

三、HashSet和HashMap的区别和联系

1、区别

HashSel HashMap
HashSet实现了Set接口 HashMap实现了Map接口
HashSet仅仅存储对象 HashMap储存键值对
使用add()方法将元素放入set中 使用put()方法将元素放入map中
HashSct使用成员对象来计算hashcodc值,对于两个对象来说hashCode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false,即添加该元素 HashMap中使用键(key)对象来计算
hashCode
HashSet较HashMap来说比较慢 HashMap比较快,因为是使用唯一的键
来获取对象
HashSet允许具有单个空值。 HashMap允许单个null键和任意数量的空值。
HashSet不允许重复元素,这意味着您无法在HashSet中存储重复值。 HashMap不允许有重复键,但它可以有重复值

2、联系

对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,更确切的说,HashSet中的元素,只是存放在了底层HashMap的key上, 而value使用一个static final的Object对象标识。


目录
相关文章
|
存储 Java
每日一道面试题之谈一谈HashMap和HashSet的区别
每日一道面试题之谈一谈HashMap和HashSet的区别
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
67 0
|
3天前
|
存储 安全 Java
如何优雅地回答HashSet与HashMap的区别?看这里!
哈喽,大家好!我是小米,29岁程序员。本文聚焦Java开发中经典的面试题——HashSet和HashMap的区别。HashSet基于HashMap实现,存储唯一值;HashMap存储键值对。两者在数据结构、使用场景、操作方法等方面有显著差异。HashSet无序且依赖元素的hashCode和equals方法保证唯一性,而HashMap需注意线程安全问题。掌握这些知识点,助你轻松应对面试。更多技术干货,欢迎关注我的微信公众号“软件求生”。
18 4
|
7月前
并发编程之的HashSet和HashMap的详细解析
并发编程之的HashSet和HashMap的详细解析
51 0
|
7月前
并发编程之的HashSet和HashMap的详细解析
并发编程之的HashSet和HashMap的详细解析
27 0
|
7月前
|
存储 安全 Java
Java HashMap 和 HashSet 的高效使用技巧
HashMap 是一种哈希表,它存储键值对。键用于查找值,就像数组中的索引一样。HashMap 的优势在于它可以使用任何类型作为键,并且查找速度很快。
113 1
|
7月前
|
算法 Java 容器
Java Review - HashMap & HashSet 源码解读
Java Review - HashMap & HashSet 源码解读
52 0
Java Review - HashMap & HashSet 源码解读
|
7月前
|
存储 缓存 Rust
Rust 笔记:Rust 语言中哈希结构(哈希映射,HashMap)、集合(哈希集,HashSet)及其使用
Rust 笔记:Rust 语言中哈希结构(哈希映射,HashMap)、集合(哈希集,HashSet)及其使用
1035 0
|
SQL Oracle Java
HashMap使用/HashSet使用 && 数据库知识_ && 基础-增删改 && 基础-查询 && 基础-增删改 && 数据库约束 &&_聚合查询
HashMap使用/HashSet使用 && 数据库知识_ && 基础-增删改 && 基础-查询 && 基础-增删改 && 数据库约束 &&_聚合查询
42 0
|
存储 缓存 Rust
Rust 笔记:Rust 语言中映射(HashMap)与集合(HashSet)及其用法
本文介绍 Rust 中哈希结构相关概念及其使用。在 Rust 中,提供了两种哈希表,一个是 HashMap,另外一个是 HashSet,本文都将逐一介绍,并介绍 哈希函数 的用法。
325 0