按日期对数组列表中的对象排序?

我发现的每个示例都是按字母顺序执行此操作,而我需要按日期对元素进行排序。

MyArrayList 包含的对象中有一个数据成员是 DateTime 对象。在 DateTime 中,我可以调用这些函数:

lt() // less-than
lteq() // less-than-or-equal-to

为了比较,我可以这样做:

if(myList.get(i).lt(myList.get(j))){
// ...
}

我应该在 if 块中做什么?

525955 次浏览

可以使用 Collections.sort 方法。这是一种静态方法。将列表和比较器传递给它。它对列表使用修改后的合并排序算法。这就是为什么你必须传递一个比较器来进行配对比较。

Collections.sort(myList, new Comparator<MyObject> {
public int compare(MyObject o1, MyObject o2) {
DateTime a = o1.getDateTime();
DateTime b = o2.getDateTime();
if (a.lt(b))
return -1;
else if (a.lteq(b)) // it's equals
return 0;
else
return 1;
}
});

注意,如果 myList 属于可比较类型(实现可比较接口的类型)(如 Date、 Integer 或 String) ,则可以省略比较器,并使用自然排序。

假设 MyObject有一个 DateTime成员和一个 getDateTime()方法,您可以按照 DateTime对象对包含 MyObject元素的 ArrayList进行排序,如下所示:

Collections.sort(myList, new Comparator<MyObject>() {
public int compare(MyObject o1, MyObject o2) {
return o1.getDateTime().lt(o2.getDateTime()) ? -1 : 1;
}
});

你可以让你的对象具有可比性:

public static class MyObject implements Comparable<MyObject> {


private Date dateTime;


public Date getDateTime() {
return dateTime;
}


public void setDateTime(Date datetime) {
this.dateTime = datetime;
}


@Override
public int compareTo(MyObject o) {
return getDateTime().compareTo(o.getDateTime());
}
}

然后通过调用:

Collections.sort(myList);

但是有时候您不想更改模型,比如当您想对几个不同的属性进行排序时。在这种情况下,您可以动态创建比较器:

Collections.sort(myList, new Comparator<MyObject>() {
public int compare(MyObject o1, MyObject o2) {
return o1.getDateTime().compareTo(o2.getDateTime());
}
});

但是,只有在比较时确定 dateTime 不为 null 时,上述方法才有效。处理 null 以避免 NullPointerException 是明智的:

public static class MyObject implements Comparable<MyObject> {


private Date dateTime;


public Date getDateTime() {
return dateTime;
}


public void setDateTime(Date datetime) {
this.dateTime = datetime;
}


@Override
public int compareTo(MyObject o) {
if (getDateTime() == null || o.getDateTime() == null)
return 0;
return getDateTime().compareTo(o.getDateTime());
}
}

或者在第二个例子中:

Collections.sort(myList, new Comparator<MyObject>() {
public int compare(MyObject o1, MyObject o2) {
if (o1.getDateTime() == null || o2.getDateTime() == null)
return 0;
return o1.getDateTime().compareTo(o2.getDateTime());
}
});

我发现这里的所有答案对于一个简单的问题来说并不一定复杂(至少对于一个有经验的 Java 开发人员来说是这样的,而我并不是)。我也遇到过类似的问题,偶然发现了这个(和其他)解决方案,虽然它们提供了一个指针,但对于一个初学者来说,我发现正如上面所述。我的解决方案,取决于您的 Date 在 Object 中的位置,在本例中,Date 是 Object []的第一个元素,其中 DataVector是包含对象的 ArrayList。

Collections.sort(dataVector, new Comparator<Object[]>() {
public int compare(Object[] o1, Object[] o2) {
return ((Date)o1[0]).compareTo(((Date)o2[0]));
}
});

随着 Java 1.8的引入,流对于解决这类问题非常有用:

Comparator <DateTime> myComparator = (arg1, arg2)
-> {
if(arg1.lt(arg2))
return -1;
else if (arg1.lteq(arg2))
return 0;
else
return 1;
};


ArrayList<DateTime> sortedList = myList
.stream()
.sorted(myComparator)
.collect(Collectors.toCollection(ArrayList::new));

这可能是一个老的响应,但是我使用了这篇文章中的一些例子来创建一个比较器,该比较器将按照列表中的一个对象(即时间戳)对 HashMap<String, String>ArrayList进行排序。

我有这些东西:

ArrayList<Map<String, String>> alList = new ArrayList<Map<String, String>>();

地图对象如下:

Map<String, Object> map = new HashMap<>();
// of course this is the actual formatted date below in the timestamp
map.put("timestamp", "MM/dd/yyyy HH:mm:ss");
map.put("item1", "my text goes here");
map.put("item2", "my text goes here");

这个映射是我用来在一个循环中使用 alList.add(map)函数将所有对象加载到数组列表中的。

现在,我创建了自己的比较器:

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;


public class DateSorter implements Comparator {
public int compare(Object firstObjToCompare, Object secondObjToCompare) {
String firstDateString = ((HashMap<String, String>) firstObjToCompare).get("timestamp");
String secondDateString = ((HashMap<String, String>) secondObjToCompare).get("timestamp");


if (secondDateString == null || firstDateString == null) {
return 0;
}


// Convert to Dates
DateTimeFormatter dtf = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss");
DateTime firstDate = dtf.parseDateTime(firstDateString);
DateTime secondDate = dtf.parseDateTime(secondDateString);


if (firstDate.isAfter(secondDate)) return -1;
else if (firstDate.isBefore(secondDate)) return 1;
else return 0;
}
}

我现在可以随时调用数组上的 Compator,它会对我的数组进行排序,给出位置0(列表顶部)的 Latest 时间戳和列表末尾的最早时间戳。新的帖子基本上被放在了顶部。

Collections.sort(alList, new DateSorter());

这也许能帮到别人,所以我才发了这个。考虑比较()函数中的 return 语句。有三种类型的结果。如果它们相等,返回0; 如果第一个日期在第二个日期之前,返回 > 0; 如果第一个日期在第二个日期之后,返回 < 0。如果您希望您的列表被颠倒,那么只需切换这两个 return 语句!Simple = ]

我就是这么解决的:

Collections.sort(MyList, (o1, o2) -> o1.getLastModified().compareTo(o2.getLastModified()));

希望对你有帮助。

在参数中传递数组列表。

    private static void order(ArrayList<Object> list) {


Collections.sort(list, new Comparator() {


public int compare(Object o2, Object o1) {


String x1 =  o1.Date;
String x2 =  o2.Date;


return  x1.compareTo(x2);


}
});
}

因为 Java8的 名单接口提供了 排序方法。结合 Lambda表达式最简单的解决方案将是

// sort DateTime typed list
list.sort((d1,d2) -> d1.compareTo(d2));
// or an object which has an DateTime attribute
list.sort((o1,o2) -> o1.getDateTime().compareTo(o2.getDateTime()));
// or like mentioned by Tunaki
list.sort(Comparator.comparing(o -> o.getDateTime()));

反向排序

Java8还提供了一些方便的反向排序方法。

//requested by lily
list.sort(Comparator.comparing(o -> o.getDateTime()).reversed());
list.sort(Comparator.comparing(o -> o.getDateTime()));

恕我直言,Tunaki 使用 Java 8 lambda 的最佳答案

使用下面的方法来标识日期是否排序

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");


boolean  decendingOrder = true;
for(int index=0;index<date.size() - 1; index++) {
if(simpleDateFormat.parse(date.get(index)).getTime() < simpleDateFormat.parse(date.get(index+1)).getTime()) {
decendingOrder = false;
break;
}
}
if(decendingOrder) {
System.out.println("Date are in Decending Order");
}else {
System.out.println("Date not in Decending Order");
}
}

Date 类已经实现了 Compaator 接口:

public class A {


private Date dateTime;


public Date getDateTime() {
return dateTime;
}


.... other variables


}

假设你有一个 A 对象的列表作为 List<A> aList,你可以很容易地用 Java8的流 API 对它进行排序(下面的片段) :

import java.util.Comparator;
import java.util.stream.Collectors;


...


aList = aList.stream()
.sorted(Comparator.comparing(A::getDateTime))
.collect(Collectors.toList())

未来的观众朋友们,我认为这是最简单的解决方案,如果你的模型包含一个字符串类型的日期(例如“2020-01-0110:00:00”) ,那么只需要写下一行,按照日期从最新到最旧的顺序对数据进行排序:

Collections.sort(messages, (o1, o2) -> o2.getMessageDate().compareTo(o1.getMessageDate()));

以下是我如何实现这一目标的答案:

Mylist.sort(Comparator.comparing(myClass::getStarttime));