2017-04-05 33 views
0

我有一個由Spring Data JPA Repository返回的Java 8流。我不認爲我的用例是非常不尋常的,有兩個(實際上是3個),我想收集的結果流中的集合。Java 8 JPA存儲庫流產生兩個(或更多)結果?

Set<Long> ids = // initialized 
try (Stream<SomeDatabaseEntity> someDatabaseEntityStream = 
      someDatabaseEntityRepository.findSomeDatabaseEntitiesStream(ids)) { 
    Set<Long> theAlphaComponentIds = someDatabaseEntityStream 
      .map(v -> v.getAlphaComponentId()) 
      .collect(Collectors.toSet()); 
    // operations on 'theAlphaComponentIds' here 
} 

我需要拉出'Beta'對象並對這些對象做一些工作。所以我認爲我必須重複代碼,這似乎是完全錯誤的:

try (Stream<SomeDatabaseEntity> someDatabaseEntityStream = 
      someDatabaseEntityRepository.findSomeDatabaseEntitiesStream(ids)) { 
    Set<BetaComponent> theBetaComponents = someDatabaseEntityStream 
      .map(v -> v.getBetaComponent()) 
      .collect(Collectors.toSet()); 
    // operations on 'theBetaComponents' here 
} 

這兩個代碼塊在處理中是連續發生的。是否有乾淨的方式讓這兩個集合只處理一次流?注意:我不想要一些構成Alpha和Beta版包裝類的kludgy解決方案,因爲它們並不真正屬於一個整體。

回答

2

您可以隨時通過將通用部件放入方法並將不常見部件轉換爲參數來重構代碼。例如。

public <T> Set<T> getAll(Set<Long> ids, Function<SomeDatabaseEntity, T> f) 
{ 
    try(Stream<SomeDatabaseEntity> someDatabaseEntityStream = 
     someDatabaseEntityRepository.findSomeDatabaseEntitiesStream(ids)) { 
     return someDatabaseEntityStream.map(f).collect(Collectors.toSet()); 
    } 
} 

可通過

Set<Long> theAlphaComponentIds = getAll(ids, v -> v.getAlphaComponentId()); 
// operations on 'theAlphaComponentIds' here 

Set<BetaComponent> theBetaComponents = getAll(ids, v -> v.getBetaComponent()); 
// operations on 'theBetaComponents' here 

注意這個拉「上......這裏操作」部分出try塊,這是一件好事的,因爲它意味着相關的資源被更早地釋放。這要求BetaComponent可以獨立於Stream的底層資源進行處理(否則,您不應將其收集到Set中)。對於Long,我們確信它們可以被獨立處理。

當然,即使沒有將公共代碼移動到方法中,您也可以處理try塊以外的結果。原始代碼是否需要重構需要重複,這是值得商榷的。實際上,該操作由try塊中的單個語句組成,僅由於冗長標識符而看起來很大。問問自己,你是否仍然認爲重構必要的,如果代碼看起來像

Set<Long> alphaIDs, ids = // initialized 
try(Stream<SomeDatabaseEntity> s = repo.findSomeDatabaseEntitiesStream(ids)) { 
    alphaIDs = s.map(v -> v.getAlphaComponentId()).collect(Collectors.toSet()); 
} 
// operations on 'theAlphaComponentIds' here 

那麼,不同的開發人員可能會得出不同的結論......


如果你想減少倉庫數量查詢,您可以簡單地店鋪查詢結果:

List<SomeDatabaseEntity> entities; 
try(Stream<SomeDatabaseEntity> someDatabaseEntityStream = 
    someDatabaseEntityRepository.findSomeDatabaseEntitiesStream(ids)) { 
    entities=someDatabaseEntityStream.collect(Collectors.toList()); 
} 
Set<Long> theAlphaComponentIds = entities.stream() 
    .map(v -> v.getAlphaComponentId()).collect(Collectors.toSet()); 
// operations on 'theAlphaComponentIds' here 
Set<BetaComponent> theBetaComponents = entities.stream() 
    .map(v -> v.getBetaComponent()).collect(Collectors.toSet()); 
// operations on 'theBetaComponents' here 
相關問題