我遇到一个问题,我认为我必须结合我正在阅读的几个概念,但是我似乎无法找出一种将它们结合在一起的方法,或者说是最有效的方法。这是我的情况:
我正在使用微服务,这就是为什么这是如此奇怪的原因。本质上,我从另一个服务获取卷对象列表。一个卷对象包含三个字段,一个字符串类型,一个字符串日期(它实际上以" HH:mm"格式表示时间,将命名约定归咎于数据建模者),以及一个int close。
我想做的是获取此对象列表并按日期(时间)排序,然后创建一个新的对象列表,其中将包含相同的日期(时间),但根据我的计算将具有不同的字段值在做。为了按时间排序,我相信我需要将时间字段转换为Date对象,然后进行比较。我正在努力如何遍历对象并比较转换后的字段。我觉得已经把我放在正确的道路上了:这是如何使用"对象名称"字段按字母顺序对List 进行排序
但是我似乎无法正常工作。这是我的代码:
volumeResources.sort(volumeResources, new Comparator(){
@Override
public int compare(VolumeResource v1, VolumeResource v2) {
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
try {
Date d1 = format.parse(v1.getDate());
Date d2 = format.parse(v2.getDate());
} catch (ParseException e) {
log.error("Error in parsing string to date.", e);
}
return d1.compareTo(d2);
}
});
现在,立即开始,我知道这一定是不正确的,因为我开始比较VolumeResources v1和v2,但是尝试比较最后的日期。除了上面的return语句,我还尝试了下面的语句,但是我认为这不会一直有效,因为它实际上没有将格式化对象设置为Date对象:
return format.parse(v1.getDate()).compareTo(format.parse(v2.getDate()));
那就是我迷路的地方。当用伪代码描述时,这似乎是一个相当简单的需求,但是我似乎无法弄清楚如何使其在功能上起作用。奖励积分是,如果有一种方法,我可以轻松地填充我需要的其他字段。使用lambda或帮助我提高效率的双倍奖励积分。
感谢您提供的所有帮助。
你到底是什么问题? 您的程序如何无法按预期执行?
可以编译吗?
@Marvin这个主要问题试图找出如何通过时间字符串对对象列表进行排序。
如果您使用的是Java 8及更高版本,则按时间排序(以String表示)可能如下所示:
volumeResources.sort(new Comparator() {
@Override
public int compare(VolumeResource v1, VolumeResource v2) {
return v1.getDate().compareTo(v2.getDate());
}
});
在Java 8之前的版本中,它应该类似于:
Collections.sort(volumeResources, new Comparator() {
@Override
public int compare(VolumeResource v1, VolumeResource v2) {
return v1.getDate().compareTo(v2.getDate());
}
});
使用lambda:
volumeResources.sort((v1, v2) -> v1.getDate().compareTo(v2.getDate()));
假定volumeResources是填充的可变List(不是null),并且所有条目的日期字段都正确填充了格式正确的时间(没有空格,制表符或前导0缺失)
说明
根据您对date字段的定义,它自然可以作为字符串进行排序,您无需将它们转换为java Date类。
您的示例通过使用List界面中定义的Java 8 sort方法以使用实用程序类Collections的方式比以前的Java 8更早的方式遇到问题-这是错误的,您不需要提供collection作为第一个参数。
感谢您的协助。我向janos提到我还有一个警告,这是我尚未意识到的事情,但是一旦我弄清楚了,便会进行调查。可以说时间是" 23:30"," 24:00"," 24:30:"," 01:00"," 01:30"," 02:00"。这将意味着经过午夜,然后需要随后。我该如何处理?
@Crislips是否可以提供错误定义的时间与正确定义的时间混合的示例,以及您期望将错误时间的条目放置在已排序列表中的期望?
如果我正确理解您的意思,这就是我的意思。我需要按发生顺序查看这些时间,而不仅仅是数字。所以可以说我有一个@Vladimir L的情况,时间跨过午夜,时间按顺序增加。我需要一个对象列表,排序方式如下:" 23:30"," 24:00"," 24:30:"," 01:00"," 01:30"," 02: 00"。但是使用当前代码,它们将被排序为:" 01:00"," 01:30"," 02:00"," 23:30"," 24:00"," 24:30:"
@Crislips您如何确定订购的开始时间?如果" 01:30"记录属于具有" 23:30"记录的一天而不属于第二天,并且恰好是在记录" 23:30"之后输入的,该怎么办?我的意思是,假设有一个序列:" 17:50"," 01:30"," 17:40"," 20:30"," 23:12"," 01:31"," 01:30" -最后应该如何排序?
因此,数字之间始终具有相同的间隔。"第一个数字"是开始时间,而":最后一个数字"将是当前时间。时间将在两者之间均匀分布。因此,如果它们在一夜之间发生,这将是显而易见的,因为它们将以明显的方式增加。
@Crislips记录是否已按时间排序?如果是,那为什么还要再次按时间对它们进行排序?您的需求确实令人困惑,我想一个很好的数据示例可能会有所帮助,您可以通过pastebin.com共享它
因此,当传递到前端时,顺序无关紧要。但是由于我需要在特定时间按升序填充对象的字段,因此在后端对我来说很重要。该列表可能不会总是按顺序提供给我,因此在使用它之前,我需要确定其顺序。因此,Im认为的伪代码将是:从其他服务获取列表->按时间排序->将具有空类型并关闭的新对象填充,但将有序时间填充到新列表中->使用Ive的关闭计算更新这些对象made->返回新的对象列表
Java中的日期必须具有年,月,日。
但是您没有这样的值,只有HH:mm(小时,分钟)。
在这里使用日期不合适。
(并且将这些值称为"日期"也很奇怪,我建议重命名。)
请注意,格式正确的HH:mm可以按字母顺序排序以正确排序。因此,您要做的就是确保输入时间遵循\d\d:\d\d模式。如果得到例如9:15,则在左侧添加填充0。像这样:
volumeResources.sort(volumeResources, new Comparator() {
@Override
public int compare(VolumeResource v1, VolumeResource v2) {
return sanitized(v1.getDate()).compareTo(sanitized(v2.getDate());
}
});
sanitized方法供您相应地实现。
如果这些值已经是String类型的正确格式,则可以删除这些调用并将其简化为:
return v1.getDate().compareTo(v2.getDate();
使用lambda:
volumeResources.sort(volumeResources, (v1, v2) -> sanitized(v1.getDate()).compareTo(sanitized(v2.getDate()));
谢谢你的建议。数据约定不是由我确定的,因此与数据建模人员进行的战斗并不值得。我知道日期是一个不好选择的名字。我猜在这种情况下,我可以使用LocalDateTime代替,但是您写的肯定更干净。我还有一个警告,这是我还没有做过的事情,但是一旦我弄清楚了,我就会去研究。可以说时间是" 23:30"," 24:00"," 24:30:"," 01:00"," 01:30"," 02:00"。这将意味着经过午夜,然后需要随后。我该如何处理?
据我所知,这就是要求的程度。我在原始答案中尽量做到简洁,但完全忘记了这一点。但是时代需要保持原样,直到最后的回报。
@Crislips所有重要要求都应在问题中说明。理想情况下,带有示例输入和预期输出,尤其是您需要处理的棘手的极端情况。如果您忘记这样做,那么在收到答案后就太迟了,无法更改。在这种情况下使用此网站的正确方法是提出一个新问题。并确保下次包含所有重要细节。
在最初提出问题时,这真的没有发生在我身上。后来我意识到了这一点,但老实说,我认为它需要改变数据从其他服务传递给我的方式。这不是那么强大。