簡體   English   中英

在Java中存儲大量配置

[英]Storing large amount of configurations in java

我有一個包含2條信息的數據類型(我們稱之為數據):

int config
byte weight

此數據類型是一系列32個布爾值的轉換。 我必須對這32個布爾值進行更改,然后將其轉換回此數據類型並存儲。 問題是我只想存儲唯一的條目,消除任何重復。 問題是此數據類型存在2 ^ 33種可能的配置。

我已經嘗試過這樣的事情:

static class searchedconfigs {
    Data[] searchedconfigs;
    int position;
    public searchedconfigs() {
        searchedconfigs = new Data[150000];
    }
    public void initiateposition() {
        position = 0;
    }
    public boolean searchfield(Data Key, int entries) {
        boolean exists = false;
        for (int i = 0; i <= entries; i++) {
            if (searchedconfigs[i] == Key) {
                System.out.println("break");
                exists = true;
                break;
            }
        }
        return exists;
    }
    public void add(Data config, int position) {
        searchedconfigs[position] = config;
    }
    public int getPosition() {
        return position;
    }
    public void storePosition() {
        position++;
    }
}

位置初始化完成並且增加完成,因此每次我僅在占用位置搜索數組時。 我的問題是,您可以看到數組的大小僅為1500000。我需要更大一些。 但是,即使分配一個最大大小為int的整數(我需要很長的時間才能構成一個我實際需要的大小的數組)也會導致內存不足錯誤。 此外,我的搜索字段功能似乎無法正確比較存儲在此位置的鍵和配置。

誰能告訴我該如何解決這些錯誤,或者建議使用其他方法來存儲這些數據。

使用HashSet ,並在Data實現equalshashCode ,如下所示:

import java.util.Objects;

class Data {
    int config;
    byte weight;

    @Override
    public int hashCode() {
        return Objects.hash(config, weight);
    }

    @Override
    public boolean equals(Object other) {
        if (other == null) return false;
        if (!(other instanceof Data)) return false;
        if (other == this) return true;

        return this.config == other.config && this.weight == other.weight;
    }
}

任何類型的Set都不包含任何重復的元素。 由於您的Data類似乎是一個值類型(即,在進行相等性比較時,成員值比其標識更重要),因此,如果無法實現這兩種方法,仍然會在您選擇的數據結構中留下重復項。

您實際遇到的空間限制是什么? Java中的數組限於Integer.MAX_VALUE(2 ^ 31-1?)。 你超車了嗎?

  • 數組中元素的最大數量?
  • 堆分配給JVM了嗎?
  • 機器上可用的RAM +交換空間?

如果這是元素的數量,請查看備用數據結構(請參見下文)。 如果要覆蓋堆,則應為應用程序分配更多內存(運行程序時,將-Xmx arg分配給JVM)。 如果您實際用完了存儲空間,節省空間的竅門只會使您大步向前。 最終數據增長將超過那些東西。 此時,您需要查看水平縮放(分布式計算)或垂直縮放(獲得具有更多RAM的更大包裝盒)。

如果您只是因為數組大小不能超過max int而使數組超支,並且確實需要考慮空間問題,那么我將避免使用HashSet,因為它比直接的List / Array或替代Set實現(例如, TreeSet中。

為了使HashSet有效地工作,它們需要一個超大的哈希表以減少空間中的哈希沖突次數。 Java中的HashSet的默認加載因子為75%,這意味着當它超過該容量時,它將調整自身大小以保持在加載因子之下。 通常,您需要為更大的空間進行交易,以便更快地插入/刪除/查找集合中的元素,我認為這是恆定時間(Big O為1)。

TreeSet只要求您的存儲容量與元素數相同(開銷可以忽略不計),但是要以增加的搜索和插入時間為對數(Log(n)的Big O)作為代價。 列表具有類似的存儲特性(取決於所使用的實現),但是如果無序,則搜索時間為N。 (您可以很好地記錄不同列表實現的各種插入/刪除/搜索時間以及有序與無序的關系)

我只想說明一下,在使用HashSet時,您在犧牲空間效率來縮短查找時間(Big O of 1)。 您必須為哈希表分配空間,該空間必須大於集合中元素的總數。 (當然,需要注意的是,您可以通過使用可怕的散列函數將存儲桶的大小基本設置為1,這可以有效地使您回到無序列表的性能特征上;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM