2016-02-11 52 views
2

我得到一個300 json要在內存中緩存一天的對象列表。在執行應用程序期間,我想通過屬性查詢對象。如何通過屬性查詢內存對象?

例子:

@XmlRootElement(name = "persons") 
@XmlAccessorType(XmlAccessType.FIELD) 
class PersonsDTO { 
    private List<PersonDTO> persons; 

    public static class PersonDTO { 
     private String name; 
     private int age; 
     //lots of more attributes 
     private Address address; 
    } 
} 

在這裏,我想運行類似查詢數據庫,如:

findByname("john doe"); 
findByAgeBetween(10, 18); 

問:我如何能夠最好地準備數據的那些「查詢」查詢?爲每個查詢函數創建一個HashMap,然後我可以返回預先計算的結果?

或者是否有任何「類似數據庫」的內存系統,我可以使用,可以查詢類似於真正的數據庫?

+0

多久會這樣的查詢被執行? – Thomas

回答

3

我只想蠻力它,除非你有特殊的性能要求類似。掃描300個條目應少於0.1毫秒。

這將允許您使用內置的流API。

private List<PersonDTO> persons; 

public List<PersonDTO> findBy(Predicate<PersionDTO> test) { 
    return persons.stream().filter(test).collect(Collectors.toList()); 
} 


// findByName 
List<PersonDTO> david = findBy(p -> p.getName().startsWith("David ")); 

// find by age 
List<PersonDTO> youngAdult= findBy(p -> p.getAge() >= 18 && p.getAge() <= 30); 
3

您可以使用基於內存數據庫的SQL,如DerbyHSQLDB。 您可以使用基於內存數據庫的NoSQL,如hazelcastMapDB。 您可以使用支持查詢的緩存解決方案,如EHCache

但300個物體很小。如果你真的需要(也就是對它進行大量的查詢),你可以遍歷它們並且在數組中有'em',並且只添加基於Map的索引。

這一切都歸結到:

  1. 你多久去查詢這個數據集?
  2. 查詢是否固定(我想喬布萊克),固定查詢參數(我希望每個人都稱爲X)或自由格式?

如果你很少去查詢數據集,並且查詢被參數修復/修復,那麼我只需循環遍歷數據集(Java 8 Streams API;最簡單的解決方案)。 如果你需要很多次點擊數據集,但有固定查詢,那麼我會預先計算結果。 如果您需要使用少量帶參數的固定查詢來大量使用數據集,那麼我會考慮添加一些自制索引(哈希映射)。 如果您需要自由格式查詢,我會考慮使用內存數據庫(NoSQL或SQL)或Java 8 Streams API。

2

HSQLDB是用Java編寫的內存中的SQL數據庫。

否則,您將需要設計和構建自己的引擎。你可能有專門的方法名稱,就像你顯示的那樣,並且避免了一些查詢解析方面的問題,但是你仍然需要實現查詢本身,但是你需要定義匹配(精確,部分,區分大小寫等)。

1

300並不是一個很大的數字(雖然斯巴達人和波斯人可能會爭辯這一點......)。

  1. 因此,在一個簡單的解決方案,你可以只保留你的對象列表中,只是遍歷列表和峯值所需要的屬性的對象。這是非常低效的,但對於300它將工作得很好。

  2. 一個步驟的位,如果你使用Java 8工作,你可以使用並行流 和濾波,這將利用自己的處理器資源的最好方式 。仍然不是非常有效。

  3. 另一個想法 - 爲每個對象添加或生成一個唯一的ID,並創建一個你的ID到您的DTO的母校映射 。然後爲您要搜索的每個 屬性創建單獨的地圖。每張地圖應該將屬性 的值保存到具有該值的DTO的ID列表中。然後您查詢 您的房產地圖查找ID,然後搜索您的主地圖 查找DTO。一般來說,這是經典的 性能與空間之間的折衷。

1

在Java8你可以只使用流爲這個簡單的任務。當然,您需要評估它是否足夠滿足您的需要,但這是一種非常快速且簡單的實現方法,無需安裝本地數據庫。

public List<PersonDTO> findByAgeBetween(min, max){ 
    List<PersonDTO> byAge = 
     personList.stream(). 
     filter(p -> p.age >= min). 
     filter(p -> p.age <= max). 
     collect(Collectors.toList()); 
    return byAge; 
} 

而對於其他查詢

相關問題