限制和分组流

huangapple go评论74阅读模式
英文:

Limit and grouping stream

问题

我有一个实体:

public class Item {

    private String name;
    private int amount;
    private String description;
    private LocalDate reportDay;

    // 构造函数和getter、setter方法
    
}

每天我想获取过去3天的关于“Items”的信息(以报告视图显示)。我有一个仓库:

@Repository
public interface ItemRepository extends JpaRepository<Item, Long> {

    @Query(value = "SELECT item from Item item where item.reportDate >= :daysAgoDate order by item.reportDate desc")
    List<Item> findAllWithDateAfter(@Param("daysAgoDate") LocalDate daysAgoDate);

}

以及为此编写的服务:

@Service
public class ItemService {

    private final ItemRepository itemRepository;

    public List<Item> getItemsForRequiredDays(int days) {
        LocalDate daysAgoDate = LocalDate.now().minusDays(days);
        return itemRepository.findAllWithDateAfter(daysAgoDate);
    }
}

它可以正常工作。但现在我想要限制提取的行数。如果从查询中获取的items超过20个,我想要限制并按天分组。所以我想要获取只有20行(限制),并且每天只有10行(按日期分组)。

我的方法应该如下所示:

public List<Item> getItemsForRequiredDays(int days) {
    LocalDate daysAgoDate = LocalDate.now().minusDays(days);
    List<Item> items = itemRepository.findAllWithDateAfter(daysAgoDate);
    int size = items.size();
    if (size > 20) {
        return items.stream()
                .limit(20)
                .collect(Collectors.groupingBy(Item::getReportDate, Collectors.toList()))
                .values().stream()
                .flatMap(sublist -> sublist.stream().limit(10))
                .collect(Collectors.toList());
    } else {
        return items;
    }
}

如何实现这个?我在分组方面遇到了困难。

英文:

I have an entity:

public class Item {

    private String name;
    private int amount;
    private String description;
    private LocalDate reportDay;

//getters and setters with constructors
    
}

Everyday I want to get information about my Items for last 3 days (in report view). I have repository:

@Repository
public interface ItemRepository extends JpaRepository&lt;Item, Long&gt; {

    @Query(value = &quot;SELECT item from Item item where item.reportDate &gt;= :daysAgoDate order by item.reportDate desc&quot;)
    List&lt;Item&gt; findAllWithDateAfter(@Param(&quot;daysAgoDate&quot;) LocalDate daysAgoDate);

}

And service for this:

@Service
public class ItemService {

    private final ItemRepository itemRepository;

    public List&lt;Item&gt; getItemsForRequiredDays(int days) {
        LocalDate daysAgoDate = LocalDate.now().minusDays(days);
        return itemRepository.findAllWithDateAfter(daysAgoDate);
    }
}

It works okay. But now I want to limit extracted rows. If I'll get more than 20 items from my query, I want to limit and group it by days. So I want to get only 20 rows (limit), and only 10 rows for per day (groupingby)

My method should looks like:

 public List&lt;Item&gt; getItemsForRequiredDays(int days) {
        LocalDate daysAgoDate = LocalDate.now().minusDays(days);
        List&lt;items&gt; items = itemRepository.findAllWithDateAfter(daysAgoDate);
        int size = items.size();
        if (size &gt; 20) {
            return items.stream()
                    .limit(20)
                    .collect(Collectors.groupingBy(Item::getReportDate, //here i want to group by date -&gt; only 10 rows for each day));
        }
        else {
            return items;
        }
    }

How to do this? I'm stuck with grouping.

答案1

得分: 1

你是否想要:

return items.stream()
            .limit(20)
            .collect(Collectors.groupingBy(Item::getReportDay))
            .values().stream()
            .flatMap(items -> items.stream().limit(10))
            .collect(Collectors.toList());

这将返回多行具有多个日期的数据,每个日期最多可以出现10次。

英文:

Are you looking to:

return items.stream()
        .limit(20)
        .collect(Collectors.groupingBy(Item::getReportDay))
        .values().stream()
        .flatMap(items -&gt; items.stream().limit(10))
        .collect(Collectors.toList());

This will return a multiple rows with multiple dates, and each date can present at max 10 times.

答案2

得分: 1

你可以按照ReportDate进行排序,然后按ReportDate进行分组。然后使用flatMap对每天的项目进行展开,每天最多限制10个项目,然后总共限制20个项目。

return items.stream()
        .sorted(Comparator.comparing(Item::getReportDate).reversed()) //如果你需要前20个项目
        .collect(Collectors.groupingBy(Item::getReportDate,
                    LinkedHashMap::new, Collectors.toList()))
        .values()
        .stream()
        .flatMap(items -> items.stream().limit(10))
        .limit(20)
        .collect(Collectors.toList());
英文:

You can sort by ReportDate then groupingBy ReportDate. Then flatten the item using flatMap limit on maximum 10 item perDay then limit 20 item only.

return items.stream()
        .sorted(Comparator.comparing(Item::getReportDate).reversed()) //If you need top 20 
        .collect(Collectors.groupingBy(Item::getReportDate,
                    LinkedHashMap::new, Collectors.toList()))
        .values()
        .stream()
        .flatMap(items -&gt; items.stream().limit(10))
        .limit(20)
        .collect(Collectors.toList());

huangapple
  • 本文由 发表于 2020年10月9日 18:34:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/64278312.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定