欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java如何實(shí)現(xiàn)海量數(shù)據(jù)判重

 更新時(shí)間:2023年09月19日 09:16:00   作者:Java中文社群  
在海量數(shù)據(jù)如何確定一個(gè)值是否存在?這是一道非常經(jīng)典的面試場(chǎng)景題,那怎么回答這個(gè)問(wèn)題呢?下面小編就來(lái)和大家詳細(xì)的聊一聊,感興趣的可以一起學(xué)習(xí)一下

在海量數(shù)據(jù)如何確定一個(gè)值是否存在?這是一道非常經(jīng)典的面試場(chǎng)景題。

那怎么回答這個(gè)問(wèn)題呢?接下來(lái)咱們就詳細(xì)的聊一聊。

參考答案

判斷一個(gè)值是否存在?通常有以下兩種解決方案:

  • 使用哈希表:可以將數(shù)據(jù)進(jìn)行哈希操作,將數(shù)據(jù)存儲(chǔ)在相應(yīng)的桶中。查詢時(shí),根據(jù)哈希值定位到對(duì)應(yīng)的桶,然后在桶內(nèi)進(jìn)行查找。這種方法的時(shí)間復(fù)雜度為 O(1),但需要額外的存儲(chǔ)空間來(lái)存儲(chǔ)哈希表。如果桶中存在數(shù)據(jù),則說(shuō)明此值已存在,否則說(shuō)明未存在。
  • 使用布隆過(guò)濾器:布隆過(guò)濾器是一種概率型數(shù)據(jù)結(jié)構(gòu),用于判斷一個(gè)元素是否在集合中。它利用多個(gè)哈希函數(shù)映射數(shù)據(jù)到一個(gè)位數(shù)組,并將對(duì)應(yīng)位置置為 1。查詢時(shí),只需要對(duì)待查詢的數(shù)據(jù)進(jìn)行哈希,并判斷對(duì)應(yīng)的位是否都為 1。如果都為 1,則該數(shù)據(jù)可能存在;如果有一個(gè)位不為 1,則該數(shù)據(jù)一定不存在。布隆過(guò)濾器的查詢時(shí)間復(fù)雜度為 O(k),其中 k 為哈希函數(shù)的個(gè)數(shù)。

相同點(diǎn)和不同點(diǎn)

它們兩的相同點(diǎn)是:它們都存在誤判的情況。例如,使用哈希表時(shí),不同元素的哈希值可能相同,所以這樣就產(chǎn)生誤判了;而布隆過(guò)濾器的特征是,當(dāng)布隆過(guò)濾器說(shuō),某個(gè)數(shù)據(jù)存在時(shí),這個(gè)數(shù)據(jù)可能不存在;當(dāng)布隆過(guò)濾器說(shuō),某個(gè)數(shù)據(jù)不存在時(shí),那么這個(gè)數(shù)據(jù)一定不存在。

它們兩的區(qū)別主要有以下幾點(diǎn):

  • 存儲(chǔ)機(jī)制:哈希表使用一個(gè)數(shù)組來(lái)存儲(chǔ)鍵值對(duì),通過(guò)哈希函數(shù)將鍵映射到數(shù)組的索引位置,然后將值存儲(chǔ)在對(duì)應(yīng)的位置上。而布隆過(guò)濾器則使用一個(gè)位數(shù)組(或位向量),通過(guò)多個(gè)哈希函數(shù)將元素映射到位數(shù)組的多個(gè)位上。
  • 查詢操作:哈希表在進(jìn)行查詢時(shí),通過(guò)計(jì)算哈希值來(lái)定位鍵值對(duì)的存儲(chǔ)位置,然后直接獲取對(duì)應(yīng)的值。查詢時(shí)間復(fù)雜度通常為 O(1)。布隆過(guò)濾器在進(jìn)行查詢時(shí),也通過(guò)多個(gè)哈希函數(shù)計(jì)算多個(gè)位,然后判斷對(duì)應(yīng)的位是否都為 1 來(lái)確定元素是否存在。查詢時(shí)間復(fù)雜度為 O(k),其中 k 為哈希函數(shù)的個(gè)數(shù)。
  • 內(nèi)存占用:哈希表需要根據(jù)數(shù)據(jù)規(guī)模來(lái)動(dòng)態(tài)調(diào)整數(shù)組的大小,以保證存儲(chǔ)效率。而布隆過(guò)濾器在預(yù)先設(shè)置位數(shù)組的大小后,不會(huì)隨數(shù)據(jù)規(guī)模的增加而增長(zhǎng)。因此布隆過(guò)濾器更適用于海量數(shù)據(jù)。

結(jié)論

哈希表和布隆過(guò)濾器都能實(shí)現(xiàn)判重,但它們都會(huì)存在誤判的情況,但布隆過(guò)濾器存儲(chǔ)占用的空間更小,更適合海量數(shù)據(jù)的判重。

布隆過(guò)濾器實(shí)現(xiàn)原理

布隆過(guò)濾器的實(shí)現(xiàn),主要依靠的是它數(shù)據(jù)結(jié)構(gòu)中的一個(gè)位數(shù)組,每次存儲(chǔ)鍵值的時(shí)候,不是直接把數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)結(jié)構(gòu)中,因?yàn)檫@樣太占空間了,它是利用幾個(gè)不同的無(wú)偏哈希函數(shù),把此元素的 hash 值均勻的存儲(chǔ)在位數(shù)組中,也就是說(shuō),每次添加時(shí)會(huì)通過(guò)幾個(gè)無(wú)偏哈希函數(shù)算出它的位置,把這些位置設(shè)置成 1 就完成了添加操作。

當(dāng)進(jìn)行元素判斷時(shí),查詢此元素的幾個(gè)哈希位置上的值是否為 1,如果全部為 1,則表示此值存在,如果有一個(gè)值為 0,則表示不存在。因?yàn)榇宋恢檬峭ㄟ^(guò) hash 計(jì)算得來(lái)的,所以即使這個(gè)位置是 1,并不能確定是那個(gè)元素把它標(biāo)識(shí)為 1 的,因此布隆過(guò)濾器查詢此值存在時(shí),此值不一定存在,但查詢此值不存在時(shí),此值一定不存在。

并且當(dāng)位數(shù)組存儲(chǔ)值比較稀疏的時(shí)候,查詢的準(zhǔn)確率越高,而當(dāng)位數(shù)組存儲(chǔ)的值越來(lái)越多時(shí),誤差也會(huì)增大。

位數(shù)組和 key 之間的關(guān)系,如下圖所示:

如何實(shí)現(xiàn)布隆過(guò)濾器

布隆過(guò)濾器的實(shí)現(xiàn)通常有以下兩種方案:

  • 通過(guò)程序?qū)崿F(xiàn)(內(nèi)存級(jí)別方案):使用 Google Guava 庫(kù)和 Apache Commons 庫(kù)實(shí)現(xiàn)布隆過(guò)濾器。
  • 通過(guò)中間件實(shí)現(xiàn)(支持?jǐn)?shù)據(jù)持久化):使用 Redis 4.0 之后提供的布隆過(guò)濾插件來(lái)實(shí)現(xiàn),它的好處是支持持久化,數(shù)據(jù)不會(huì)丟失。

Guava 實(shí)現(xiàn)布隆過(guò)濾器

使用 Google Guava 庫(kù)實(shí)現(xiàn)布隆過(guò)濾器總共分為以下兩步:

  • 引入 Guava 依賴
  • 使用 Guava API 操作布隆過(guò)濾器

具體實(shí)現(xiàn)如下。

① 引入 Guava 依賴

<dependency>
????<groupId>com.google.guava</groupId>
????<artifactId>guava</artifactId>
</dependency>

② 使用 Guava API

import?com.google.common.hash.BloomFilter;
import?com.google.common.hash.Funnels;
public?class?BloomFilterExample?{
????public?static?void?main(String[]?args)?{
????????//?創(chuàng)建一個(gè)布隆過(guò)濾器,設(shè)置期望插入的數(shù)據(jù)量為10000,期望的誤判率為0.01
????????BloomFilter<String>?bloomFilter?=?BloomFilter.create(Funnels.unencodedCharsFunnel(),?10000,?0.01);
????????//?向布隆過(guò)濾器中插入數(shù)據(jù)
????????bloomFilter.put("data1");
????????bloomFilter.put("data2");
????????bloomFilter.put("data3");
????????//?查詢?cè)厥欠翊嬖谟诓悸∵^(guò)濾器中
????????System.out.println(bloomFilter.mightContain("data1"));?//?true
????????System.out.println(bloomFilter.mightContain("data4"));?//?false
????}
}

在上述示例中,我們通過(guò) BloomFilter.create() 方法創(chuàng)建一個(gè)布隆過(guò)濾器,指定了元素序列化方式、期望插入的數(shù)據(jù)量和期望的誤判率。然后,我們可以使用 put() 方法向布隆過(guò)濾器中插入數(shù)據(jù),使用 mightContain() 方法來(lái)判斷元素是否存在于布隆過(guò)濾器中。

小結(jié)

在海量數(shù)據(jù)如何確定一個(gè)值是否存在?通常有兩種解決方案:哈希表和布隆過(guò)濾器,而它們兩都存在誤判的情況,但布隆過(guò)濾器更適合海量數(shù)據(jù)的判斷,因?yàn)樗加玫臄?shù)據(jù)空間更小。布隆過(guò)濾器的特征是:當(dāng)布隆過(guò)濾器說(shuō),某個(gè)數(shù)據(jù)存在時(shí),這個(gè)數(shù)據(jù)可能不存在;當(dāng)布隆過(guò)濾器說(shuō),某個(gè)數(shù)據(jù)不存在時(shí),那么這個(gè)數(shù)據(jù)一定不存在。

到此這篇關(guān)于Java如何實(shí)現(xiàn)海量數(shù)據(jù)判重的文章就介紹到這了,更多相關(guān)Java數(shù)據(jù)判重內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java字符串編碼知識(shí)點(diǎn)詳解介紹

    Java字符串編碼知識(shí)點(diǎn)詳解介紹

    在本篇內(nèi)容了小編給大家詳細(xì)分析了關(guān)于Java字符串編碼的知識(shí)點(diǎn)并對(duì)實(shí)例做了分析,有興趣的朋友們跟著學(xué)習(xí)下。
    2022-11-11
  • Java中joda日期格式化工具的使用示例

    Java中joda日期格式化工具的使用示例

    這篇文章主要介紹了Java中joda日期格式化工具的使用示例,幫助大家更好的利用Java處理時(shí)間,感興趣的朋友可以了解下
    2021-01-01
  • SpringBoot中配置文件pom.xml的使用詳解

    SpringBoot中配置文件pom.xml的使用詳解

    SpringBoot的pom.xml文件是Maven項(xiàng)目的核心配置文件,用于定義項(xiàng)目的依賴、插件、構(gòu)建配置等信息,下面小編就來(lái)和大家詳細(xì)介紹一下它的具體使用吧
    2025-03-03
  • IntelliJ IDEA 的使用界面圖文教程

    IntelliJ IDEA 的使用界面圖文教程

    這篇文章主要介紹了IntelliJ IDEA 的使用界面圖文教程,需要的朋友可以參考下
    2018-10-10
  • 深入理解Java 對(duì)象和類

    深入理解Java 對(duì)象和類

    下面小編就為大家?guī)?lái)一篇深入理解Java 對(duì)象和類。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-05-05
  • Java IO流常用字節(jié)字符流原理解析

    Java IO流常用字節(jié)字符流原理解析

    這篇文章主要介紹了Java IO流常用字節(jié)字符流原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • spring中@Autowire和@Resource的區(qū)別在哪里(推薦)

    spring中@Autowire和@Resource的區(qū)別在哪里(推薦)

    這篇文章主要介紹了spring中@Autowire和@Resource的區(qū)別在哪里?本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • 基于java socket實(shí)現(xiàn) 聊天小程序

    基于java socket實(shí)現(xiàn) 聊天小程序

    這篇文章主要介紹了基于java socket實(shí)現(xiàn) 聊天小程序,代碼分為服務(wù)器和客戶端,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Mybatis源碼解析之初始化分析

    Mybatis源碼解析之初始化分析

    這篇文章主要介紹了Mybatis源碼解析之初始化分析,Mybatis的初始化過(guò)程就是mybatis配置文件的解析過(guò)程并將解析結(jié)果保存到Configuration類。,需要的朋友可以參考下
    2024-01-01
  • SpringBoot調(diào)用Poi-tl實(shí)現(xiàn)渲染數(shù)據(jù)并生成Word文檔

    SpringBoot調(diào)用Poi-tl實(shí)現(xiàn)渲染數(shù)據(jù)并生成Word文檔

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何調(diào)用Poi-tl實(shí)現(xiàn)渲染數(shù)據(jù)并生成Word文檔,文中的示例代碼講解詳細(xì),有需要的小伙伴可以了解下
    2023-09-09

最新評(píng)論