如何遍历对象列表,转换字段,比较字段,然后按该字段排序?

时间:2017-07-11 20:41:05

标签: java list sorting compare listiterator

我遇到了一个问题,我认为我必须结合我正在阅读的几个概念,但我似乎无法找到一种方法来将它们组合起来,这是有意义的,或者是最有效的。这是我的情况:

我正在使用微服务,这就是为什么这是如此奇怪的具体。基本上我从另一个服务获得一个Volume对象列表。一个卷对象包含三个字段,一个字符串类型,一个字符串日期(实际上表示时间格式为" HH:mm",责备命名约定的数据建模者)和一个int close。

我要做的是获取此对象列表并按日期(时间)排序,然后创建一个新的对象列表,其中包含相同的日期(时间),但将具有基于的不同字段值我正在做的计算。为了按时间排序,我相信我需要将时间字段转换为Date对象,然后比较它们。我正在努力如何遍历对象并比较转换后的字段。我觉得有些让我走上正确道路的是:How to sort a List<Object> alphabetically using Object name field

但我似乎无法让它发挥作用。这是我的代码:

volumeResources.sort(volumeResources, new Comparator<VolumeResource>(){
        @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()));

这就是我迷失的地方。当用伪代码描述时,这似乎是一个相当简单的需求,但我似乎无法弄清楚如何使它在功能上工作。奖励积分如果我可以通过这种方式轻松填充我需要的其他字段。使用lambdas或帮助我提高效率的双倍奖励积分。

感谢所有人的帮助。

2 个答案:

答案 0 :(得分:1)

Java中的日期必须包含年,月,日。 但是你没有这样的价值观,你只有HH:mm(小时,分钟)。 在这里使用日期是不合适的。 (并且调用这些值&#34; date&#34;也很奇怪,我建议重命名。)

请注意,格式正确的HH:mm可以按字母顺序排序,以便正确排序。所以你需要做的就是确保输入时间遵循\d\d:\d\d模式。如果您获得9:15,请在左侧添加填充0。像这样:

volumeResources.sort(volumeResources, new Comparator<VolumeResource>() {
    @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()));

答案 1 :(得分:1)

如果您使用的是Java 8及更高版本,则按时间排序(表示为String)可能如下所示:

    volumeResources.sort(new Comparator<VolumeResource>() {
        @Override
        public int compare(VolumeResource v1, VolumeResource v2) {
            return v1.getDate().compareTo(v2.getDate());
        }
    });

在Java 8之前,它应该如下所示:

    Collections.sort(volumeResources, new Comparator<VolumeResource>() {
        @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类。

您的示例使用sort接口中定义的Java 8 List方法存在问题,其方式与以前使用实用程序类Collections之前的Java 8相同 - 这是错误的,您不需要提供集合作为第一个参数。