在java中存储大量配置

在java中存储大量配置,java,arrays,Java,Arrays,我有一个数据类型(我们称之为data),它包含两条信息: int config byte weight 此数据类型是一系列32个布尔值的转换。我必须对这32个布尔值进行更改,将其转换回此数据类型并存储。 问题是我只想存储唯一的条目,消除任何重复项。问题是此数据类型存在2^33种可能的配置 我试过这样的方法: static class searchedconfigs { Data[] searchedconfigs; int position; public search

我有一个数据类型(我们称之为data),它包含两条信息:

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++;
    }
}
静态类searchedconfigs{
数据[]搜索配置;
内部位置;
公共搜索配置(){
searchedconfigs=新数据[150000];
}
公共无效初始位置(){
位置=0;
}
公共布尔搜索字段(数据键,int条目){
布尔存在=假;
对于(int i=0;i使用a,并在
数据中实现和,如下所示:

导入java.util.Objects;
类数据{
int-config;
字节权重;
@凌驾
公共int hashCode(){
return Objects.hash(配置,权重);
}
@凌驾
公共布尔等于(对象其他){
if(other==null)返回false;
如果(!(数据的其他实例))返回false;
if(other==this)返回true;
返回this.config==other.config&&this.weight==other.weight;
}
}

任何类型的都不包含任何重复元素。因为您的
数据
类似乎是一种值类型(即,在比较是否相等时,成员值比其标识更重要),如果未能实现这两种方法,仍会在您选择的数据结构中留下重复项。

您实际遇到的空间限制是什么?java中的数组限制为Integer.MAX_值(2^31-1?)。是否超限:

  • 数组中的最大元素数
  • 分配给JVM的堆
  • 机器上可用的RAM+交换空间
如果是元素数,那么请查看另一种数据结构(见下文)。如果堆溢出,则应为应用程序分配更多内存(-Xmx arg,在运行程序时分配给JVM)。如果您的机箱内存不足,那么节省空间的技巧只会让您走到这一步;最终数据增长将超过这些。在这一点上,您需要考虑水平扩展(分布式计算)或垂直扩展(使用更多RAM获得更大的机箱)

如果您只是因为数组的大小不能超过max int而导致数组溢出,那么我会避免使用HashSet,因为它比直接列表/数组或替代集实现(如树集)占用更多的空间

为了使哈希集高效地工作,它们需要一个超大的哈希表来减少空间中哈希冲突的数量。Java中的哈希集的默认负载因子为75%,这意味着当它超过该容量时,它会将自身的大小调整得更大,以保持在负载因子之下。通常情况下,为了更快地插入,您需要交换更大的空间n/删除/查找集合中元素的时间,我认为这是一个常数时间(大O为1)

树集应该只要求您的存储容量与元素数相同(开销可以忽略不计),但要权衡增加的搜索和插入时间(对数大O(n))。列表具有类似的存储特性(取决于使用的实现)但如果是无序的,则搜索时间为N。(您可以查找不同列表实现的各种插入/删除/搜索时间&有序与无序它们都有很好的文档记录)


我只想指出,当使用哈希集时,您是在用空间效率换取更快的查找时间(大O为1)。您必须为哈希表分配空间,该空间必须大于集合中的元素总数。(当然有一个警告,你可以通过一个可怕的散列函数来强制你的bucket的大小基本上是1,这将有效地让你回到一个无序列表的性能特征上来;)

每个
数据的位置是否重要,或者您是否只需要测试其存在性/成员资格?没有任何位置是无关紧要的
HashSet
是的。HashSet实际上空间效率较低,因为默认Java实现中的负载系数为75%。一旦它满了75%,它将向上调整自身大小。列表/数组或替代集实现(如TreeSet)将比哈希集更节省空间。区别在于与每个实现相关联的查找时间:哈希集的常量时间,log(n)对于treeset,“n”表示无序列表。@dev.glitch我认为还应该注意到,虽然使用有序集合可能会提高空间复杂性,但这是以时间复杂性为代价的。在这种情况下,需要进行大量计算。因此,这肯定是您必须记住的