我有一张按天索引的工作班次图map
"2020-03-26": [
{
"id": 4,
"startTime": "21:00:00"
},
{
"id": 5,
"startTime": "09:00:00",
}
],
"2020-03-27": [
{
"id": 4,
"startTime": "22:00:00"
},
{
"id": 5,
"startTime": "10:00:00",
}
],
...
]
可以看到,班次有一个id和一个开始时间。
但将地图按天索引是一种浪费:变化碰巧是一致的,除了一件事。开始时间是
LocalTime
,因此班次的唯一区别是,在应用时区后,当DST翻转发生时,产生的班次仅在小时内不同。
我想在收集器中执行某种
groupBy
,以获得类似的功能:
Range.of(2020-01-01 ... 2020-03-26) [
{
"id": 4,
"startTime": "21:00:00"
},
{
"id": 5,
"startTime": "09:00:00",
}
],
Range.of(2020-03-27 ... 2020-10-30) [
{
"id": 4,
"startTime": "22:00:00"
},
{
"id": 5,
"startTime": "10:00:00",
}
],
Range.of(2020-10-31 ... 2021-01-01) [
{
"id": 4,
"startTime": "21:00:00"
},
{
"id": 5,
"startTime": "09:00:00",
}
]
...分组在从DST翻转到DST翻转的
范围内。我很难写一个
收集器。groupBy(…)
并将密钥从单个LocalDate
day转换为范围
首先,您需要定义一个具有两个字段(开始日期和结束日期)的类Range
,并创建一个范围列表。由于只需要三个实例,因此将此列表声明为实用程序类中的公共静态最终
字段是有意义的。
下面是范围的一个例子
,为了简洁起见,我将其实现为Java 16 record。给出了一种实用方法,用于检查给定日期是否在此范围内:
public record Range(LocalDate start, LocalDate end) {
public boolean isWithinRange(LocalDate date) { // start inclusive, end exclusive
return date.isBefore(start) || date.isBefore(end) && date.isAfter(start);
}
}
范围列表:
public static final List<Range> RANGES =
List.of(new Range(LocalDate.of(2020,1, 1), LocalDate.of(2020,3, 27)),
new Range(LocalDate.of(2020,3, 27), LocalDate.of(2020,10, 31)),
new Range(LocalDate.of(2020,10, 31), LocalDate.of(2021,1, 1)));
实用方法getRange()
负责根据给定日期从范围列表中检索Range
的实例:
public static Range getRange(LocalDate data) {
return RANGES.stream()
.filter(range -> range.isWithinRange(data))
.findFirst()
.orElseThrow();
}
虚拟记录Shift
(用于测试目的):
public record Shift(int id, LocalTime startTime) {}
为了接近地图的转换
main()
-demo
public static void main(String[] args) {
Map<LocalDate, Collection<Shift>> shiftsByDate =
Map.of(LocalDate.of(2020,3, 26),
List.of(new Shift(4, LocalTime.of(21, 0, 0)), new Shift(5, LocalTime.of(9, 0, 0))),
LocalDate.of(2020,3, 27),
List.of(new Shift(4, LocalTime.of(22, 0, 0)), new Shift(5, LocalTime.of(10, 0, 0)))
);
Map<Range, List<Shift>> shiftsByRange = shiftsByDate.entrySet().stream()
.collect(Collectors.groupingBy(entry -> getRange(entry.getKey()),
Collectors.flatMapping(entry -> entry.getValue().stream(),
Collectors.toList())));
shiftsByRange.forEach((k, v) -> System.out.println(k + " : " + v));
}
输出
Range[start=2020-10-31, end=2021-01-01] : [Shift[id=4, startTime=22:00], Shift[id=5, startTime=10:00]]
Range[start=2020-01-01, end=2020-03-27] : [Shift[id=4, startTime=21:00], Shift[id=5, startTime=09:00]]
感谢所有人!
问题内容: 抱歉,是否曾有人问过这个问题,但我进行了广泛调查,没有结果。 我想创建一个新列,该列根据某些规则映射的多个值,例如a = [1,2,3]为1,a = [4,5,6,7]为2,a = [8 ,9,10]为3。一对一映射对我来说很清楚,但是如果我想按值列表或范围进行映射怎么办? 我遵循这些原则… 问题答案: 有几种选择。 熊猫通过/ NumPy通过 NumPy通过 的元素是布尔级数,因此对
问题内容: 我正在寻找一种确定范围的方法 。 Golang规范指出以下内容: 未指定地图的迭代顺序,并且不能保证每次迭代之间都相同。如果在迭代过程中删除尚未到达的映射条目,则不会生成相应的迭代值。如果映射条目是在迭代过程中创建的,则该条目可能在迭代过程中产生或可以被跳过。对于创建的每个条目以及从一个迭代到下一个迭代,选择可能有所不同。如果映射为nil,则迭代次数为0。 我在StackOverflo
在web应用部署描述符中,以下语法用于定义映射: 以‘/’字符开始、以‘/*’后缀结尾的字符串用于路径匹配。 以‘*.’开始的字符串用于扩展名映射。 空字符串“”是一个特殊的URL模式,其精确映射到应用的上下文根,即,http://host:port//请求形式。在这种情况下,路径信息是‘/’且servlet路径和上下文路径是空字符串(“”)。 只包含“/”字符的字符串表示应用的“default”
我试图收集一个列表的结果,并将它们组织成一个地图,其中的值是一个地图: 我得到错误,因为对于列表中的不同值是相同的。 映射中包含的值应为: 当我尝试会删除其中一个条目
问题内容: 我有一个表,例如此数据 我想有一个查询,将日期分开,所以我有像这样一年中分开的金额: 2013年有25个月是因为2013年有1个月,而2014年有75个月是因为有3个月 有没有办法在T-SQL中做到这一点? 提前谢谢! 问题答案: 使用表格创建日历表格,然后将其加入表格以将日期范围划分为所需的任何部分。 如果按年份除以金额,然后除以月份,您可以: 这是SQL FIDDLE DEMO。