按字段日期对数组对象排序

时间:2019-03-08 14:03:40

标签: java

我有一个对象MyTimes,在该对象中有字段namestart_dateconfiguration

我有一个对象数组MyTimes [] mytimes

我正在尝试按开始时间对数组进行排序,但是正在努力解决这个问题。

start_time字段是一个字符串,因此需要将其转换为日期时间。

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");


for(int i=0; i<mytimes.length; i++) {
   Date date = formatter.parse(mytimes[i].getStartTime());
}

然后我可能将日期放入数组列表中,然后按日期时间排序?但后来我不知道哪个start_time与哪个mytimes对象相对应...

最有效的方法是什么?

4 个答案:

答案 0 :(得分:2)

您有两种主要方法:

  • 让您的类实现可比性
  • 使用自定义比较器

然后,您可以选择要比较的字段,然后对其进行转换。

IE(实现类似):

class Example implements Comparable<Example> { 

    private String stringDate; 

    public int compareTo(Example e) { 
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        Date date1 = formatter.parse(this.stringDate);
        Date date2 = formatter.parse(e.stringDate);
        return date1.getTime() - date2.getTime(); 
    } 
}

然后使用Arrays.sort将使用您的自定义比较。

答案 1 :(得分:2)

在适当的情况下,这是单线的:

    Arrays.sort(myTimes, Comparator.comparing(MyTimes::getStartDate));

让我们看看它的作用:

    MyTimes[] myTimes = {
            new MyTimes("Polly", "2019-03-06T17:00:00Z"),
            new MyTimes("Margaret", "2019-03-08T09:00:00Z"),
            new MyTimes("Jane", "2019-03-01T06:00:00Z")
    };

    Arrays.sort(myTimes, Comparator.comparing(MyTimes::getStartDate));

    Arrays.stream(myTimes).forEach(System.out::println);

输出:

Jane     2019-03-01T06:00:00Z
Polly    2019-03-06T17:00:00Z
Margaret 2019-03-08T09:00:00Z

我假设getStartDate返回Instant或其他类型,其自然顺序与您想要的时间顺序一致。例如:

public class MyTimes {

    private String name;
    private Instant startDate;

    // Constructor, getters, toString, etc.
}

如果您以某种方式接收开始日期作为字符串,则可以编写一个方便的构造函数,该构造函数接受一个字符串作为开始日期。我已经在上面的代码段中使用了这样的构造函数。一种可能性是有两个构造函数:

public MyTimes(String name, Instant startDate) {
    this.name = name;
    this.startDate = startDate;
}

public MyTimes(String name, String startDate) {
    this(name, Instant.parse(startDate));
}

Instant类是现代Java日期和时间API java.time的一部分。

我正在利用一个事实,即您的字符串一下子就处于ISO 8601格式,即Instant.parse接受并解析的格式。

避免使用SimpleDateFormatDate

我建议您不要使用SimpleDateFormatDate。这些类的设计很差,而且已经过时了,特别是前者非常麻烦。解析的格式模式字符串中还存在一个错误:Z(读作“ Zulu”)表示UTC,并且您不这样解析它,您将获得错误的时间(在大多数JVM上)。 Instant.parse有效地避免了这里的任何问题。

不要将date-tine存储为字符串

您似乎正在将开始时间存储在对象的String字段中?那将是糟糕的建模。使用正确的日期时间类型。字符串用于接口。像Instant这样的日期时间类提供了更多功能,例如定义排序顺序。

答案 2 :(得分:0)

使用可以编写自己的比较功能进行排序。

Arrays.sort(mytimes, 
            (a,b) -> {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
                Date date1 = formatter.parse(a);
                Date date2 = formatter.parse(b);
                return date1.getTime() - date2.getTime();
            }
        );

答案 3 :(得分:0)

让您的类使用现代格式和日期类实现import java.io.*; public class Test { public static void main(String args[]) { String Str = new String("BAU powiat augustowski"); System.out.println(Str.replaceFirst(" ", "=")); } } 并实现Comparable。请注意,compareTo还实现了Comparable,因此一旦解析了字符串,您就让LocalDateTime进行比较

LocalDateTime

如果这种比较很特殊并且您并不总是想使用什么,您还可以创建一个单独的类作为比较器

public class MyTimes implements Comparable<MyTimes>  {
     private final DateTimeFormatter dtf = DateTimeFormatter.ISO_INSTANT;

     //other code

     public int compareTo(MyTimes o) {
         LocalDateTime thisDate = LocalDateTime.from(dtf.parse(this.getStartTime()));
         LocalDateTime otherDate = LocalDateTime.from(dtf.parse(o.getStartTime()));
         return thisDate.compareTo(otherDate);
     }
}

然后像使用它

public class MyTimesComparator implements Comparator<MyTimes> {
    @Override
    public int compare(MyTimes arg0, MyTimes arg1) {
        DateTimeFormatter dtf = DateTimeFormatter.ISO_INSTANT;
        LocalDateTime thisDate = LocalDateTime.from(dtf.parse(this.getStartTime()));
        LocalDateTime otherDate = LocalDateTime.from(dtf.parse(o.getStartTime()));
        return thisDate.compareTo(otherDate);
    }
}

或使用内联函数(我在这里使用someList.sort(new MyTimesComparator());

Instant

我现在注意到您有一个数组而不是一个列表,因此您需要转换为列表或改用Arrays.sort。