按日期排序ArrayList中的对象?

时间:2011-05-08 11:19:09

标签: java sorting datetime

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

My ArrayList包含其中一个数据库是DateTime对象的对象。在DateTime上我可以调用函数:

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

为了比较我可以做类似的事情:

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

我应该在if块内做什么?

14 个答案:

答案 0 :(得分:375)

您可以使您的对象具有可比性:

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也是明智的,以避免NullPointerExceptions:

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());
  }
});

答案 1 :(得分:44)

从Java 8开始,List接口提供sort方法。结合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()))

答案 2 :(得分:18)

您可以使用Collections.sort方法。这是一种静态方法。你传递它的列表和比较器。它在列表上使用修改后的mergesort算法。这就是为什么你必须通过一个比较器进行配对比较。

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属于可比类型(实现Comparable接口的类型)(如Date,Integer或String),则可以省略比较器并使用自然顺序。

答案 3 :(得分:9)

list.sort(Comparator.comparing(o -> o.getDateTime()));

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

答案 4 :(得分:7)

如果MyObject成员DateTimegetDateTime()方法,则可以ArrayList对包含MyObject元素的DateTime进行排序像这样的对象:

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

答案 5 :(得分:4)

这就是我解决的问题:

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

希望对你有所帮助。

答案 6 :(得分:2)

通过引入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));

答案 7 :(得分:1)

我发现这里的所有答案对于一个简单的问题都是非常复杂的(至少对于经验丰富的java开发人员来说,我不是这样)。我有一个类似的问题并偶然发现这个(和其他)解决方案,虽然他们提供了一个指针,对于初学者我发现如上所述。我的解决方案取决于你的日期对象中的位置,在这种情况下,日期是Object []的第一个元素,其中 dataVector 是包含对象的ArrayList。

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

答案 8 :(得分:1)

这是我如何实现的答案:

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

答案 9 :(得分:0)

这可能是一个旧的响应,但我使用了这篇文章中的一些示例创建了一个比较器,它将ArrayList HashMap<String, String> 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; } } 函数将所有对象加载到数组列表中。

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

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

我现在可以随时在数组上调用Comparator,它将对我的数组进行排序,为我提供位置0(列表顶部)的最新时间戳和列表末尾的最早时间戳。新职位基本上处于领先地位。

.map

这可能会帮助某人,这就是我发布它的原因。考虑compare()函数中的return语句。有3种类型的结果。如果它们相等则返回0,如果第一个日期在第二个日期之前则返回&gt;如果第一个日期在第二个日期之后则返回&lt; 0。如果您想要反转列表,那么只需切换这两个返回语句!简单=]

答案 10 :(得分:0)

使用以下方法确定日期是否已排序

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");
    }       
}   

答案 11 :(得分:0)

Date类已经实现了Comparator接口。假设您有以下课程:

def game(p1, p2):
    win = ('rock','scissors'),('scissors','paper'),('paper','rock')
    p1, p2 = map(lambda x: x.lower().strip(), [p1, p2])
    if p1 == p2:
        return 'tie!'
    elif (p1, p2) in win:
        return f'player 1 wins, {p1} beats {p2}'
    elif (p2, p1) in win:
        return f'player 2 wins, {p2} beats {p1}'
    else:
        return f'invalid choice(s): {p1}, {p2}'

def _again():
    resp = input('play again?')
    return resp.lower().strip()[0] == 'y'

def play():
    p1 = input('player 1:\n')
    p2 = input('player 2:\n')
    print(game(p1, p2))
    if _again():
       play()

我们假设您有一个public class A { private Date dateTime; public Date getDateTime() { return dateTime; } .... other variables } 的A对象列表,您可以使用Java 8的流API(下面的代码段)轻松对其进行排序:

List<A> aList

答案 12 :(得分:0)

面向未来的观众,我认为这是最简单的解决方案,如果您的模型包含字符串类型的日期(例如“ 2020-01-01 10:00:00”),那么只需编写以下行即可对数据进行排序日期从最新到最早降序:

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

答案 13 :(得分:-1)

在参数中传递ArrayList。

    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);

        }
    });
}