英文:
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<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);
}
And service for this:
@Service
public class ItemService {
private final ItemRepository itemRepository;
public List<Item> 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<Item> getItemsForRequiredDays(int days) {
LocalDate daysAgoDate = LocalDate.now().minusDays(days);
List<items> items = itemRepository.findAllWithDateAfter(daysAgoDate);
int size = items.size();
if (size > 20) {
return items.stream()
.limit(20)
.collect(Collectors.groupingBy(Item::getReportDate, //here i want to group by date -> 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 -> 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 -> items.stream().limit(10))
.limit(20)
.collect(Collectors.toList());
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论