-1
votes

Comment trier les objets en fonction de la date de la chaîne en Java

Je crée une application Android dans laquelle je dois trier les objets par date. La date est stockée sous forme de String dans l'objet client. Comment puis-je le faire?

Je l'ai déjà essayé en utilisant la méthode Collection.sort() mais sans succès.

public static Comparator<Customer> dateNewOld = new Comparator<Customer>() {
       @Override
       public int compare(Customer o1, Customer o2) {
           DateFormat f = new SimpleDateFormat("dd/MM/yyyy");
           try
           {
               return f.parse(o2.date).compareTo(f.parse(o1.date));
           }
           catch (ParseException e)
           {
               e.printStackTrace();
           }
           return 0;
       }
   };

Je m'attends à ce que la sortie soit triée ArrayList mais elle n'est pas triée par date.

Mon format de date est le 19.Jul.2019 , mais cela me donne une exception insensée.


14 commentaires

Veuillez fournir un exemple complet, les données et votre code de tri ne sont pas là.


Le code semble bien. De combien vos dates sont différentes. Sont-ils différents selon les jours et les mois?


Si vous mettez la date au format année / mois / date, cela peut faciliter le tri.


Ils sont différents selon les jours, au format jj / MM / aa


Eh bien, je vous suggère de convertir le format que vous avez obtenu au format qui se penche sur le tri.


Ou vous pouvez utiliser Java LocalDate et il peut faire le travail pour vous.


Comment puis-je utiliser LocaleDate


mkyong.com/java8/java-8-how-to-convert-string-to-localdate


DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy"); LocalDate date1 = LocalDate.parse("12/02/2019", dtf); LocalDate date2 = LocalDate.parse("12/03/2019", dtf); System.out.println(date1.compareTo(date2));


Je viens de voir que ça me donne une exception irréparable


Pour info, les classes date-heure gênantes telles que java.util.Date , java.util.Calendar et java.text.SimpleDateFormat sont désormais héritées, supplantées par les classes java.time . La plupart des fonctionnalités java.time sont rétroportées vers Java 6 et Java 7 dans le projet ThreeTen-Backport . Adapté pour Android antérieur (<26) dans ThreeTenABP . Voir Comment utiliser ThreeTenABP… .


Conseil: réécrivez votre classe Customer pour contenir un objet LocalDate plutôt qu'une simple chaîne.


Veuillez publier la trace de la pile de votre exception. Cela nous en dira beaucoup sur ce qui ne va pas.


J'ai voté défavorablement parce que votre question manque de détails sur l'exception et parce que le manque d'exemple minimal et reproductible (anciennement connu sous le nom de MCVE) rend difficile la réponse .


6 Réponses :


0
votes

Selon mkyong

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date date1 = sdf.parse("2009-12-31");
    Date date2 = sdf.parse("2010-01-31");

    System.out.println("date1 : " + sdf.format(date1));
    System.out.println("date2 : " + sdf.format(date2));

    if (date1.compareTo(date2) > 0) {
        System.out.println("Date1 is after Date2");
    }


6 commentaires

Veuillez le préciser avec un exemple


Tout ce que vous avez à faire est de changer la chaîne de format. C'est aussi simple que possible. @Anaskhan


Comme dans l'exemple, avez-vous essayé avec SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


Je n'arrive toujours pas à comprendre. Pouvez-vous s'il vous plaît modifier l'exemple que j'ai donné pour l'ordre croissant


Mon format de date est le 19 juillet 2019, mais cela me donne une exception imparable


Pour info, les classes date-heure gênantes telles que java.util.Date , java.util.Calendar et java.text.SimpleDateFormat sont désormais héritées, supplantées par les classes java.time . La plupart des fonctionnalités java.time sont rétroportées vers Java 6 et Java 7 dans le projet ThreeTen-Backport . Adapté pour Android antérieur (<26) dans ThreeTenABP . Voir Comment utiliser ThreeTenABP… .



3
votes

java.time

Utilisez les classes java.time qui supplantent les anciennes classes gênantes ( java.util.Date , java.sql.Date , SimpleDateFormat ). Une implémentation des classes modernes est fournie avec Android 26 et versions ultérieures.

La plupart des fonctionnalités java.time  sont portées en arrière vers Java 6 et Java 7 dans le projet ThreeTen-Backport . Adapté pour Android antérieur (<26) dans ThreeTenABP . Voir Comment utiliser ThreeTenABP… .

LocalDate représente une valeur de date uniquement, sans heure et sans fuseau horaire.

package sortdates;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class SortDates {

    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
        Comparator<MyData> comparator = Comparator.comparing(myData -> LocalDate.parse(myData.date, formatter));
        List<MyData> set = getMyData().stream()
                .sorted(comparator)
                .collect(Collectors.toList());
        set.forEach(myData -> System.out.println(myData.date));
    }

    private static Collection<MyData> getMyData() {
        return Arrays.asList(
                new MyData("01/01/2000"),
                new MyData("01/02/2000"),
                new MyData("03/01/2002"),
                new MyData("04/06/2001")
                );
    }

    public static class MyData{
        String date;

        public MyData(String date) {
            this.date = date;
        }
    }

}


1 commentaires

J'ai ajouté un texte explicatif à votre réponse. Stack Overflow est censé être plus qu'une collection découpée. Vous devez avoir une explication de votre code, de sa motivation et de ses détails.



0
votes

La comparaison de o2 avec o1 triera votre liste par ordre décroissant.

Vous pouvez utiliser Collections.sort () ainsi que list.sort ()

J'ai créé une classe de test avec un objet client. J'espère que cet exemple vous aidera.

package project;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class SortTest
{

    public static void main(String args[])
    {
        List<Customer> list = new ArrayList<>();
        list.add( new Customer( 1, "21/07/2019" ) );
        list.add( new Customer( 2, "19/06/2019" ) );
        list.add( new Customer( 3, "20/07/2019" ) );

        Collections.sort( list, dateNewOld );
        //list.sort( dateNewOld );

        print( list );
    }

    public static Comparator<Customer> dateNewOld = new Comparator<Customer>()
    {
        @Override
        public int compare( Customer o1, Customer o2 )
        {
            DateFormat f = new SimpleDateFormat( "dd/MM/yyyy" );
            try
            {
                return f.parse( o2.date ).compareTo( f.parse( o1.date ) );
            }
            catch ( ParseException e )
            {
                e.printStackTrace();
            }
            return 0;
        }
    };

    private static void print( List<Customer> list )
    {
        for ( Customer customer : list )
        {
            System.out.println(customer);
        }
    }

    static class Customer
    {
        final int id;
        final String date;

        Customer( int id, String date )
        {
            this.id = id;
            this.date = date;
        }

        @Override
        public String toString()
        {
            return "Customer{" +
                    "id=" + id +
                    ", date='" + date + '\'' +
                    '}';
        }
    }

}


0 commentaires

0
votes

Je suppose que le problème est de savoir comment comparer les deux chaînes, voici un exemple de travail ( par ordre croissant ).

List<String> dateList = new ArrayList<>();
dateList.add("22/05/1995");
dateList.add("22/01/1995");
dateList.add("22/01/1994");
Comparator<String> dateNewOld = new Comparator<String>() {
  @Override
  public int compare(String o1, String o2) {
    DateFormat f = new SimpleDateFormat("dd/MM/yyyy");
    try {
      return f.parse(o1).compareTo(f.parse(o2));
    } catch (ParseException e) {
      e.printStackTrace();
    }
    return 0;
  }
};
dateList.sort(dateNewOld);
System.out.println(dateList);

PS: Je suppose que votre code ne trie pas à cause du return 0 dans le comparateur. Peut-être que votre code lève une exception et que vous n'avez pas vu la console!


1 commentaires

Pour info, les classes date-heure gênantes telles que java.util.Date , java.util.Calendar et java.text.SimpleDateFormat sont désormais héritées, supplantées par les classes java.time . La plupart des fonctionnalités java.time sont rétroportées vers Java 6 et Java 7 dans le projet ThreeTen-Backport . Adapté pour Android antérieur (<26) dans ThreeTenABP . Voir Comment utiliser ThreeTenABP… .



2
votes

LocalDate comme votre propriété

La meilleure solution consiste à modifier votre classe Customer pour utiliser la classe LocalDate comme type de votre propriété.

Conseil: utilisez un nom plus descriptif pour vos champs de membre qui ne date que de date .

public static Comparator< Customer > CustomerComparator = new Comparator< Customer >() 
{
    @Override
    public int compare( Customer c1 , Customer c2 ) {
        return ( c1.firstContact.compareTo( c2.firstContact ) ) ;
    }
};

Maintenant, votre Comparator devient assez simple, car la classe LocalDate implémente déjà l'interface Comparable et sa méthode compareTo .

public class Customer {
    public LocalDate firstContact ; 
    …
}

Si vous ne pouvez pas modifier le type de données de votre propriété de classe, consultez la bonne réponse d'Ezequiel .


0 commentaires

1
votes

ArrayList trie String_Dates et évite les doublons lors de l'ajout.

Ajout d'un nouvel exemple à la publication @Ezequiel.

public class CustomArrayListSet {
    //static ArrayList<String> predefinedList =  new java.util.ArrayList<String>();
    static ArrayListCustomStr<String> customList = new ArrayListCustomStr<String>();
    public static void main(String[] args) {
        String inputDatess = "15.10.2020,11.10.2020,12.10.2020,12.10.2020,18.10.2020,13.10.2020,14.10.2020,11.10.2020,"
                + "15.10.2020,15.10.2020,15.10.2020,16.10.2020,17.10.2020,18.10.2020,19.10.2020,20.10.2020,10.10.2020";
        
        String[] dates = inputDatess.split(",");
        for (int i = 0; i < dates.length; i++) {
            customList.add(dates[i]);
        }
        System.out.println("Custom ArrayList with override Add Function:\n"+customList);
        
        customList.sortDatesStrList();
        System.out.println("Sorted ArrayList:\n"+ customList );
    }
}
class ArrayListCustomStr<T> implements Set<T> {
    @Override
    public String toString() {
        StringBuffer buffer = new StringBuffer("[");
        for (int i = 0; i < entries.size(); i++) {
            buffer.append(entries.get(i));
            if ( (i+1) < entries.size() ) buffer.append(", ");
        }
        buffer.append("]");
        return buffer.toString();
    }
    public void sortDatesStrList() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
        Comparator<String> comparator = Comparator.comparing(myData -> LocalDate.parse(myData, formatter));
        ArrayList<String> sortedList = (ArrayList<String>) entries.stream()
                .sorted(comparator)
                .collect(Collectors.toList());
        entries = sortedList;
    }
    private ArrayList<String> entries;
    // Simple constructor using an array list for its entries.
    public ArrayListCustomStr() {
        super();
        entries = new ArrayList<String>();
    }
    public int size() {
        return entries.size();
    }
    public void clear() {
        entries.clear();
    }
    public boolean isEmpty() {
        return entries.isEmpty();
    }
    public Object[] toArray() {
        return entries.toArray();
    }
    public boolean add(Object o) {
        // Ignore existing entries to ensure Set interface contract
        if (entries.contains(o))
            return false;

        return entries.add((String) o);
    }
    public boolean contains(Object o) {
        return entries.contains(o);
    }
    public boolean remove(Object o) {
        return entries.remove(o);
    }
    @SuppressWarnings("unchecked")
    public boolean addAll(@SuppressWarnings("rawtypes") Collection c) {
        return entries.addAll(c);
    }
    public boolean containsAll(@SuppressWarnings("rawtypes") Collection c) {
        return entries.containsAll(c);
    }
    public boolean removeAll(@SuppressWarnings("rawtypes") Collection c) {
        return entries.removeAll(c);
    }
    public boolean retainAll(@SuppressWarnings("rawtypes") Collection c) {
        return entries.retainAll(c);
    }
    @SuppressWarnings("unchecked")
    public Iterator<T> iterator() {
        return (Iterator<T>) entries.iterator();
    }
    @SuppressWarnings("unchecked")
    public Object[] toArray(Object[] a) {
        return entries.toArray(a);
    }
}

Exemple avec Customed ArrayList pour trier et éviter les doublons:

public class ArrayListSet {
    static ArrayList<String> list =  new java.util.ArrayList<String>();
    public static void main(String[] args) {
        String inputDatess = "15.10.2020,11.10.2020,12.10.2020,12.10.2020,18.10.2020,13.10.2020,14.10.2020,11.10.2020,"
                + "15.10.2020,15.10.2020,15.10.2020,16.10.2020,17.10.2020,18.10.2020,19.10.2020,20.10.2020,10.10.2020";
        
        String[] dates = inputDatess.split(",");
        for (int i = 0; i < dates.length; i++) {
            listCustomAdd(dates[i]);
        }
        System.out.println("ArrayList with Custom Funciton for Add:\n"+list);
        
        ArrayList<String> listSorted = getSortedDatesStrList(list.stream());
        System.out.println("Sorted ArrayList:\n"+listSorted);
    }
    public static ArrayList<String> getSortedDatesStrList(Stream<String> stream) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
        Comparator<String> comparator = Comparator.comparing(myData -> LocalDate.parse(myData, formatter));
        ArrayList<String> sortedList = (ArrayList<String>) stream
                .sorted(comparator)
                .collect(Collectors.toList());
        return sortedList;
    }
    public static void listCustomAdd(String dateStr) {
        if( !list.contains(dateStr) )
            list.add(dateStr);
    }
}

0 commentaires