2016-04-02 69 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,這將有效地使你回到無序列表的性能特徵上;)