web-dev-qa-db-fra.com

Trier les objets dans ArrayList par date?

Chaque exemple que je trouve concerne la procédure alphabétique, alors que j'ai besoin que mes éléments soient triés par date.

Mon ArrayList contient des objets sur lesquels l'un des membres de la donnée est un objet DateTime. Sur DateTime je peux appeler les fonctions:

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

Donc, pour comparer, je pourrais faire quelque chose comme:

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

Que dois-je faire à l'intérieur du bloc if?

129
user393964

Vous pouvez rendre votre objet comparable:

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

Et puis vous le triez en appelant:

Collections.sort(myList);

Cependant, parfois, vous ne souhaitez pas modifier votre modèle, comme lorsque vous souhaitez effectuer un tri sur plusieurs propriétés différentes. Dans ce cas, vous pouvez créer un comparateur à la volée:

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

Toutefois, ce qui précède ne fonctionne que si vous êtes certain que dateTime n'est pas nul au moment de la comparaison. Il est également sage de gérer null pour éviter 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());
  }
}

Ou dans le deuxième exemple:

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

Depuis Java 8, l'interface List fournit la méthode sort . Combinée avec lambda expression, la solution la plus simple serait

// 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()))
51
Paul Wasilewski

Vous pouvez utiliser la méthode Collections.sort. C'est une méthode statique. Vous passez la liste et un comparateur. Il utilise un algorithme mergesort modifié sur la liste. C'est pourquoi vous devez passer un comparateur pour faire les comparaisons de paires.

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

Notez que si myList est d'un type comparable (implémentant une interface comparable) (comme Date, Integer ou String), vous pouvez omettre le comparateur et l'ordre naturel sera utilisé.

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

La meilleure réponse à mon humble avis de Tunaki en utilisant Java 8 lambda

9
Stimpson Cat

Étant donné que MyObject possède un membre DateTime avec une méthode getDateTime(), vous pouvez trier un ArrayList contenant les éléments MyObject à l'aide des objets DateTime comme cette:

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

Voici comment j'ai résolu:

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

J'espère que ça vous aidera.

4
Igor Escobar

Avec l'introduction de Java 1.8, les flux sont très utiles pour résoudre ce type de problèmes:

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

Toutes les réponses que j’ai trouvées ici m’ont semblé excessivement complexes pour un problème simple (du moins à un développeur expérimenté Java, ce que je ne suis pas). J'avais un problème similaire et je suis tombé par hasard sur cette (et d'autres) solutions, et bien qu'elles aient fourni un indicateur, pour un débutant, j'ai trouvé ce qui est indiqué ci-dessus. Ma solution dépend de l'emplacement de l'objet dans votre date. Dans ce cas, la date est le premier élément de l'objet [], où dataVector est la liste de tableaux contenant vos objets.

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

C’est peut-être une vieille réponse, mais j’ai utilisé quelques exemples de ce billet pour créer un comparateur qui trierait une ArrayList de HashMap<String, String> en fonction d’un objet de la liste, l’horodatage.

J'ai ces objets:

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

Les objets de la carte sont les suivants:

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

Ce mappage est ce que j'utilise pour charger tous mes objets dans la liste de tableaux, à l'aide de la fonction alList.add(map), au sein d'une boucle.

Maintenant, j'ai créé mon propre comparateur:

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

Je peux maintenant appeler le comparateur à tout moment sur le tableau et celui-ci triera mon tableau, me donnant l'horodatage le plus récent en position 0 (en haut de la liste) et l'horodatage le plus ancien à la fin de la liste. Les nouveaux messages sont placés au sommet.

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

Cela peut aider quelqu'un, c'est pourquoi je l'ai posté. Prenez en compte les instructions return dans la fonction compare (). Il y a 3 types de résultats. Renvoyer 0 s'ils sont égaux, renvoyer> 0 si la première date est antérieure à la deuxième date et <0 si la première date est postérieure à la deuxième date. Si vous souhaitez que votre liste soit inversée, il suffit de permuter ces deux instructions return! Simple =]

0
Brandon

La classe Date implémente déjà l'interface Comparator. En supposant que vous ayez la classe ci-dessous:

public class A {

    private Date dateTime;

    public Date getDateTime() {
        return dateTime;
    }

    .... other variables

}

Et supposons que vous ayez une liste d'objets A comme List<A> aList, vous pouvez facilement la trier avec l'API de flux de Java 8 (extrait ci-dessous):

import Java.util.Comparator;
import Java.util.stream.Collectors;

...

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

Passez l'arrayList en argument.

    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
Senghani Maulik

Utilisez l'approche ci-dessous pour identifier les dates sont triées ou non

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