2017-04-05 67 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 
相关问题