drJ*_*ava 10 java java-8 java-stream java-time
我的列表中有项目,项目有一个字段,显示项目的创建日期.
我需要根据用户提供的"压缩"对它们进行分组.选项包括Day,Week,Month和Year.
如果用户选择day压缩,我需要将我的项目分组,以便在同一天创建的项目将被分组.在上面的示例中,仅在同一天创建了第1项和第2项.其他人也是团体,但他们只有一个项目,因为在他们的日子,只创建了一个项目.
{{item1, item2}, {item3}, {item4}, {item5}, {item6}, {item7}}
Run Code Online (Sandbox Code Playgroud)
如果用户选择week:
{{item1, item2, item3, item4}, {item5}, {item6}, {item7}}
Run Code Online (Sandbox Code Playgroud)
如果用户选择month:
{{item1, item2, item3, item4, item5}, {item6}, {item7}}
Run Code Online (Sandbox Code Playgroud)
如果用户选择year:
{{item1, item2, item3, item4, item5, item6}, {item7}}
Run Code Online (Sandbox Code Playgroud)
创建组后,项目的日期并不重要.我的意思是,只要创建了组,密钥就可以是任何东西.
在使用的情况下Map,我认为按键如下:
day=一年中的一天=一年中的
week一周=一年中的
month一个月
year=一年
什么是这个问题的最佳解决方案?我甚至无法启动它,除了迭代之外我无法想到解决方案.
Fed*_*ner 27
我将使用分类器上的Collectors.groupingBy调整LocalDate,以便具有相似日期(根据用户给出的压缩)的项目组合在一起.
为此,首先创建以下内容Map:
static final Map<String, TemporalAdjuster> ADJUSTERS = new HashMap<>();
ADJUSTERS.put("day", TemporalAdjusters.ofDateAdjuster(d -> d)); // identity
ADJUSTERS.put("week", TemporalAdjusters.previousOrSame(DayOfWeek.of(1)));
ADJUSTERS.put("month", TemporalAdjusters.firstDayOfMonth());
ADJUSTERS.put("year", TemporalAdjusters.firstDayOfYear());
Run Code Online (Sandbox Code Playgroud)
注意:因为"day",TemporalAdjuster正在使用一个不受影响的日期.
接下来,使用compression用户给出的动态选择如何对项列表进行分组:
Map<LocalDate, List<Item>> result = list.stream()
.collect(Collectors.groupingBy(item -> item.getCreationDate()
.with(ADJUSTERS.get(compression))));
Run Code Online (Sandbox Code Playgroud)
的LocalDate是由进行调整LocalDate.with(TemporalAdjuster)的方法.
您可以使用 java 8 流获得您描述的行为:
Map<LocalDate, List<Data>> byYear = data.stream()
.collect(groupingBy(d -> d.getDate().withMonth(1).withDayOfMonth(1)));
Map<LocalDate, List<Data>> byMonth = data.stream()
.collect(groupingBy(d -> d.getDate().withDayOfMonth(1)));
Map<LocalDate, List<Data>> byWeek = data.stream()
.collect(groupingBy(d -> d.getDate().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))));
Map<LocalDate, List<Data>> byDay = data.stream()
.collect(groupingBy(d -> d.getDate()));
Run Code Online (Sandbox Code Playgroud)
groupingBy和collect 的文档。在所有 4 种情况下LocalDate都用作键。为了适当地分组,它被修改为使所有日期具有相同的月和日或同一天,但不同的月或同月和同一周的同一天(星期一)导致明显的分组规则。您数据中的日期不是修改的唯一键。这将考虑当年相同时月份相同,当完整日期相同时日期相同。
例如,当按月分组时,这些日期将具有相同的键:
01/01/2017 --> 钥匙 01/01/2017
04/01/2017 --> 钥匙 01/01/2017
05/01/2017 --> 钥匙 01/01/2017
当按周分组时,这些日期将具有相同的键(日期是前一个星期一):
04/01/2017 --> 关键 02/01/2017
05/01/2017 --> 关键 02/01/2017
例如,您可能希望按月份的同一天分组,而不考虑年份和月份。你会像这样实现它:
Map<Integer, List<Data>> byDayOfMonth = data.stream()
.collect(groupingBy(d -> d.getDate().getDayOfMonth()));
Run Code Online (Sandbox Code Playgroud)
将 01/01/2017 与 01/10/2017 组合在一起,然后将 05/01/2017 与 05/04/2018 组合在一起
| 归档时间: |
|
| 查看次数: |
9701 次 |
| 最近记录: |