在java中存储大量配置

时间:2016-04-02 23:31:21

标签: java arrays

我有一个包含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(我需要一个很长的数组来构成我实际需要的大小)会导致内存不足的错误。此外,我的搜索字段功能似乎无法正确比较存储在此位置的密钥和配置。

任何人都可以告诉我如何解决这些错误或建议采用不同的方法存储这些数据。

2 个答案:

答案 0 :(得分:0)

使用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类似乎是值类型(即,在比较相等性时,成员值比其身份更重要),未能实现这两种方法仍将在您选择的数据结构中留下重复。

答案 1 :(得分:0)

您实际遇到的空间限制是多少? java中的数组仅限于Integer.MAX_VALUE(2 ^ 31-1?)。你是否超支:

  • 数组中的最大元素数?
  • 分配给JVM的堆?
  • 机器上可用的RAM +交换空间?

如果是元素数量,那么请查看替代数据结构(见下文)。如果你正在超越堆,那么你应该为你的应用程序分配更多的内存(运行程序时-Xmx arg到JVM)。如果你实际上在盒子空间上节省了大量内存,那么节省的技巧只会让你到目前为止;最终数据增长将超过这些事情。此时,您需要查看水平扩展(分布式计算)或垂直扩展(获得具有更多RAM的更大的盒子)。

如果你只是超越一个数组,因为它的大小不能超过max int而且空间确实是一个问题,我会避免使用HashSet,因为它比直接的List / Array或备用Set需要更多的空间像TreeSet一样实现。

为了使HashSets高效工作,他们需要一个超大的哈希表来减少空间中的哈希冲突数量。 Java中的HashSet具有75%的默认加载因子,这意味着当它超过该容量时,它将自己调整大小以保持在负载因子之下。一般来说,你会交换更大的空间,以便更快地插入/删除/查找集合中的元素,我认为这是一个恒定的时间(Big O为1)。

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

我只想注意在使用HashSet时,您需要交换空间效率以获得更快的查找时间(Big O为1)。您必须为哈希表分配空间,该空间必须大于集合中元素的总数。 (当然有一点需要注意,你可以通过一个可怕的散列函数强制你的桶的大小基本上为1,这将有效地使你回到无序列表的性能特征;)