2016-04-02 65 views
2

大量配置中的我有一个数据类型(让我们称之为数据),其包含2条信息:存储在Java

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++; 
    } 
} 

位置开始做,增加做是为了让我每次搜索只阵中占据的位置。我的问题是,你可以看到该阵列只有150万的大小。我需要更大。然而,即使分配一个最大大小的int(我需要很长的时间来创建一个我实际需要的大小的数组)也会导致内存不足错误。此外,我的searchfield函数似乎没有正确比较存储在此位置的密钥和配置。

任何人都可以告诉我,我可以做些什么来解决这些错误或提出一种不同的方法来存储这些数据。

+0

是每个“数据”的位置都很重要,还是只需要测试存在/成员资格? – JesseTG

+0

没有位置是没有意义的 –

+0

'HashSet'就是这样。 – JesseTG

回答

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

0

你实际遇到的空间限制是什么? java中的数组仅限于Integer.MAX_VALUE(2^31-1?)。你是否超出范围:

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

如果是元素的数量,那么看看另一种数据结构(见下文)。如果你超出了堆的范围,那么你应该为你的应用程序分配更多的内存(运行你的程序时-Xmx arg到JVM)。如果你实际上在盒子上的内存不足,节省空间的技巧只会让你满意;最终数据增长将超过这些事情。此时,您需要查看水平缩放(分布式计算)或垂直缩放(获得更大RAM的更大盒子)。

如果你只是超越了一个数组,因为它的大小不能超过max int,空间是一个问题,所以我会避免使用HashSet,因为它需要比直接列表/数组或更多空间更多的空间像TreeSet一样设置实现。

为了使HashSet有效地工作,他们需要一个超大的散列表来减少空间中散列冲突的次数。 Java中的HashSet具有75%的默认加载因子,这意味着当它超过该容量时,它将调整自身的大小以保持在加载因子之下。一般来说,您交易的空间更大,可以更快地插入/移除/查找时间,因为我相信这是一个固定的时间(大1)。

TreeSet应该只需要您的存储容量与元素数量(可忽略的开销)相同,但在增加的搜索插入时间(Log(n)的大O)上进行交换。列表共享一个类似的存储特性(取决于所使用的实现),但如果它是无序的,则搜索时间为N. (你可以查看不同列表实现的各种插入/删除/搜索时间&有序与无序他们是非常有据可查的)

我只想在使用HashSet时注意,你正在交易空间效率更快的外观时间(1的大O)。您必须为散列表分配空间,该空间必须大于收集中元素的总数。 (当然,有一点需要注意的是,你可以通过使用可怕的散列函数来强制你的存储桶的大小基本上为1,这将有效地使你回到无序列表的性能特征上;)