Sortuj obiekty w ArrayList według daty?

Czy ktoś może mi z tym pomóc? Każdy przykład, który znajduję, dotyczy robienia tego Alfabetycznie, podczas gdy moje elementy muszą być posortowane według daty.

Moja ArrayList zawiera obiekty, na których jednym z datamembers jest obiekt DateTime. W DateTime mogę wywołać funkcje:

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

Więc dla porównania mógłbym zrobić coś takiego:

if(myList.get(i).lt(myList.get(j))){
    // ...
}
Nie wiem, co robić wewnątrz bloku if. Jakieś pomysły?
Author: Domchi, 2011-05-08

11 answers

Możesz uczynić swój obiekt porównywalnym:

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

A następnie sortujesz je przez wywołanie:

Collections.sort(myList);

Jednak czasami nie chcesz zmieniać modelu, na przykład gdy chcesz sortować na kilku różnych właściwościach. W takim przypadku możesz utworzyć komparator w locie:

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

Jednak powyższe działa tylko wtedy, gdy jesteś pewien, że dateTime nie jest null w momencie porównania. Dobrze jest również obsługiwać null, aby uniknąć 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());
  }
}

Lub w drugim przykład:

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());
  }
});
 336
Author: Domchi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-08 12:29:47

Od Javy 8 Interfejs List dostarcza metodę sort . W połączeniu z wyrażeniem lambda najprostszym rozwiązaniem byłoby

// 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()))
 33
Author: Paul Wasilewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-02 18:31:38

Możesz używać kolekcji.metoda sortowania. To metoda statyczna. Podajesz listę i komparator. Używa zmodyfikowanego algorytmu mergesort nad listą. Dlatego musisz przekazać go komparator, aby zrobić porównania par.

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

Zauważ, że jeśli myList jest porównywalnego typu (takiego, który implementuje porównywalny interfejs) (jak Date, Integer lub String), możesz pominąć komparator i zostanie użyta naturalna kolejność.

 18
Author: helios,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-08 11:53:06

Biorąc pod uwagę MyObject, który ma element DateTime z metodą getDateTime(), możesz sortować ArrayList, który zawiera MyObject elementy według DateTime obiektów, takich jak:

Collections.sort(myList, new Comparator<MyObject>() {
    public int compare(MyObject o1, MyObject o2) {
        return o1.getDateTime().lt(o2.getDateTime()) ? -1 : 1;
    }
});
 7
Author: WhiteFang34,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-08 11:52:57
list.sort(Comparator.comparing(o -> o.getDateTime()));

Najlepsza odpowiedź IMHO od Tunaki za pomocą Java 8 lambda

 5
Author: Stimpson Cat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-13 15:12:57

Oto jak rozwiązałem:

Collections.sort(MyList, (o1, o2) -> o1.getLastModified().compareTo(o2.getLastModified()));
Mam nadzieję, że ci pomoże.
 4
Author: Igor Escobar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-18 21:09:33

Wszystkie odpowiedzi, które tu znalazłem, okazały się nie-konieczne do skomplikowania prostego problemu(przynajmniej dla doświadczonego programisty Javy, którym nie jestem). Miałem podobny problem i chased na ten (i inne) rozwiązania, i choć podali wskaźnik, dla początkującego znalazłem jak wspomniano powyżej. Moje rozwiązanie zależy od tego, gdzie w obiekcie znajduje się data, w tym przypadku Data jest pierwszym elementem obiektu [], gdzie dataVector jest ArrayList zawierającym Twoje obiekty.

Collections.sort(dataVector, new Comparator<Object[]>() {
    public int compare(Object[] o1, Object[] o2) {
        return ((Date)o1[0]).compareTo(((Date)o2[0]));
    }
});
 1
Author: Nepaluz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-09 11:27:28

Wraz z wprowadzeniem Javy 1.8, strumienie są bardzo przydatne w rozwiązywaniu tego rodzaju problemów:

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));
 1
Author: Tinki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-06 18:09:35
 0
Author: bpgergo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-08 11:26:48

To może być stara odpowiedź, ale użyłem kilku przykładów z tego postu, aby utworzyć komparator, który posortowałby ArrayList z HashMap<String, String> według jednego obiektu na liście, czyli znacznika czasu.

Mam te obiekty:

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

Obiekty mapy są następujące:

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

To mapowanie jest tym, czego używam do załadowania wszystkich moich obiektów do listy tablic, za pomocą funkcji alList.add(map), wewnątrz pętli.

Teraz stworzyłem swój własny komparator:

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

Mogę teraz po prostu zadzwonić do komparatora w dowolnym momencie na tablicy i posortuje moją tablicę, dając mi najnowszy znacznik czasu na pozycji 0 (Góra listy) i najwcześniejszy znacznik czasu na końcu listy. Nowe posty trafiają na szczyt.

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

To może komuś pomóc, dlatego to zamieściłem. Weź pod uwagę polecenia return w funkcji compare (). Istnieją 3 rodzaje wyników. Zwraca 0, jeśli są równe, zwraca >0, Jeśli pierwsza data jest przed drugą datą i zwraca

 0
Author: Brandon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-03 17:33:35

Podaj ArrayList w argumencie.

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

        }
    });
}
 0
Author: Senghani Maulik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-04 09:57:48