1

I have 2 lists which are holding the same objects but unordered and I want to sort them first before comparing them in order to check whether they are equals.

One item of each list looks like that:

first list:

AuditRow{dateStr='2019-04-15 11:16', userStr='admin', entityStr='Users'}

second list:

AuditRow{dateStr='2019-04-15 10:28', userStr='admin', entityStr='Users'}

I tried to use Comparator for this issue but with no success I must say that both of the list got more than 10 items.

I want to achieve the goal of sorting up my lists by their date time (mostly relying on hour since the date is the same for all the items).

This is what I tried:

    Override
    public int compareTo(AuditRow auditRow) {
        int compareage = Integer.parseInt(((AuditRow)auditRow).dateStr.replace(" ",""));
        return Integer.parseInt(this.dateStr.replace(" ",""))-compareage; 
    }

But this did not do the trick

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
tupac shakur
  • 658
  • 1
  • 12
  • 29
  • 5
    `Comparator` would be the right way to go. What did you try there, and what wasn't successful about it? – BeUndead Apr 15 '19 at 08:37
  • how you want to sort them. and paste what you have tried already. – MD Ruhul Amin Apr 15 '19 at 08:39
  • @user2478398 this is what I tried: Override public int compareTo(AuditRow auditRow) { int compareage = Integer.parseInt(((AuditRow)auditRow).dateStr.replace(" ","")); return Integer.parseInt(this.dateStr.replace(" ",""))-compareage; } But this did not do the trick – tupac shakur Apr 15 '19 at 09:02
  • Thanks for the additional information. Please always add such in the question itself. Only this time I did it for you. – Ole V.V. Apr 15 '19 at 10:24
  • Don’t store date and time as string inside your `AuditRow` objects. `LocalDateTime` would be the type to use for date and time if you don’t know the time zone. If you do, `ZonedDateTime` or `Instant` would be even more appropriate. Then just use `Comparator.comparing(ar -> ar.dateTime)`. Or even better, provide a getter instead of exposing a public field. – Ole V.V. Apr 15 '19 at 10:30
  • Like in [this answer by Jeroen Steenbeeke](https://stackoverflow.com/a/47282919/5772882). Search for many more good answers (only ignore those using the long outdated `SimpleDateFormat` class). – Ole V.V. Apr 15 '19 at 10:36

3 Answers3

2

if you want to sort them by the dateStr:

list.sort((obj1,obj2) ->{SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm");
return sdf.parse(obj1.getDate()).compareTo(sdf.parse(obj2.getDate());}

I assumed the dateStr is a string, so I included the conversion here, if they already are dates, then simply do (obj1,obj2) -> obj1.getDate().compareTo(obj2.getDate())

EDIT: as @RobertKock pointed out, you don't even need to convert the string to a date, you can straight up compare it without any conversion.

vc73
  • 407
  • 3
  • 15
  • 1
    Since the dateStr (in case it's actually a string), is formatted in YYYYMMDD HHMM, the alphabetical order coincides with the chronological one. No need to convert it into a date therefore. – Robert Kock Apr 15 '19 at 08:53
  • @vc73what is the list in your example and do you insert both of the lists to be compared? – tupac shakur Apr 15 '19 at 09:03
  • it's just one of the lists you need to sort out, obj1 and obj2 are the AuditRow objects. – vc73 Apr 15 '19 at 09:47
  • 1
    While the answer looks correct and I agree in parsing the datetime string, please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. – Ole V.V. Apr 15 '19 at 10:26
  • 1
    I'm just gonna say I agree with @vc73 and think you _should_ convert the `String` to a `Date`. Just because the examples don't have time zones or similar, it doesn't mean that none of the data does (and even still, it just makes it less brittle IMO). – BeUndead Apr 15 '19 at 16:12
1

I don't know what you tried with comparator. Have you tried using like this:

First you create a comparator, by the field you want to use in your case date time.

Comparator<AuditRow> compareByDate = (AuditRow a1, AuditRow a2) -> a1.getDateStr().compareTo(a2.getDateStr());

Then you use the above created comparator as param in sort:

Collections.sort(auditRowList, compareByDate);
Laguh
  • 621
  • 2
  • 10
  • 23
1

Using comparator:

List(AuditRow) myList;
Collections.sort(myList, new Comparator<AuditRow>{
    public int compare(AuditRow ar1, AuditRow ar2) {
        return ar1.getDateStr().compareTo(ar2.getDateStr());
    }
});

Same as above, but using lambda expressions (Java 8+):

List(AuditRow) myList;
Collections.sort(myList, (ar1, ar2) -> 
        ar1.getDateStr().compareTo(ar2.getDateStr()});

If your comparator is created from comparing properties then you can use:

List(AuditRow) myList;
myList.sort(myList, 
        Comparator.comparing(AuditRow::getDateStr)
            .thenComparing(AuditRow::userStr));