【问题标题】:How to filter stream of Page<E> by stream Java 11 API in Spring boot app [closed]如何在 Spring Boot 应用程序中通过流 Java 11 API 过滤 Page<E> 的流 [关闭]
【发布时间】:2023-03-08 13:37:01
【问题描述】:

我有以下方法和数据:-

public Page<MydataDTO> getData(){
    // here var data is Page<MydataDTO>
    var data = this.dataRepository.findAll(specification, pageable) 
                                        .map(MydataDTO::from);

   if(startOfDay != null && atEndOfDay != null){
        Instant finalStartOfDay = startOfDay;
        Instant finalAtEndOfDay = atEndOfDay;
   // here var filteredData is Lit<MydataDTO>       
   var filteredData = vv.stream().filter(e -> e.getCreated().isAfter(finalStartOfDay) && e.getCreated().isBefore(finalAtEndOfDay))
   .collect(Collectors.toList());

    }
}

因为我必须从此函数返回 Page。如何拟合数据并从此函数返回页面?我可以将列表转换为页面吗?也许是的,但出于性能原因,我不应该这样做。因为将 Page 转换为 List 并再次转换回 Page 听起来很疯狂。对于大型收藏品,这是非常糟糕的。我怎样才能有效地做到这一点?

【问题讨论】:

  • Page 是什么类?你能把Javadoc链接到它吗?添加适当的标签可能会有所帮助。
  • 您的评论说,“这里的 var 数据是 Page”是很好的提示,您应该明确声明变量类型而不使用类型推断。当人类可以很容易地从右手表达式中看到左手类型是什么时,类型推断非常有用。例如。我可以很容易地看到filterDataList;我看不出它的泛型是什么。
  • 什么是vvminimal reproducible example 将有助于解决您的问题并将其与不相关的细节隔离开来。

标签: java java-stream filtering


【解决方案1】:

假设您已经扩展 JpaSpecificationExecutor&lt;MydataDTO&gt; 如果没有请扩展 JpaSpecificationExecutor

尝试动态构建查询并通过查询进行过滤,而不是先获取结果然后过滤

final Optional<Date> after = Optional.ofNullable(startOfDay);
final Optional<Date> before = Optional.ofNullable(atEndOfDay);

Specification<MydataDTO> inBetweenDates = null; 

if(before.isPresent() && after.isPresent()) {
    inBetweenDates = (root, query, cb) -> {
        return cb.between(root.get("created"), after.get(), before.get());
    };
}

dataRepository.findAll(inBetweenDates, pageable); 

【讨论】:

    【解决方案2】:

    最好的选择是通过在您的规范中添加按日期过滤来获取已过滤的数据。 如果你想按照你说的那样做,你必须使用过滤列表创建一个新页面。

    @Autowired
    private UserRepository userRepository;
    
    @Test
    public void test1() {
        Pageable pageable = PageRequest.of(0, 10,  Sort.by(Order.desc("id")));
        Page<User> page = userRepository.findAll(pageable);
        
        Page<User> pageWithFilteredData = new PageImpl<User>(page.stream().filter(user -> user.getName().contains("john"))
        .collect(Collectors.toList()), page.getPageable(), page.getSize());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 2018-06-05
      • 1970-01-01
      相关资源
      最近更新 更多