繁体   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