2

I'd like to sort list of my objects by one argument it's date in format "YYYY-MM-DD HH:mm" by ascending order. I can't find a right solution. In python It's easily to sort it using lambda, but in Java I've a problem with it.

for (Shop car : cars) {
             Collections.sort(cars, new Comparator<Shop>() {
                @Override
                public int compare(final Shop car, final Shop car) {
                    return car.getDate().compareTo(arc.getDate());
            }
        });

Thanks in advance!

11
  • is it a date or string of that type? if it is a date which java object do you use? Commented Apr 15, 2017 at 13:36
  • It's a string of that type Commented Apr 15, 2017 at 13:37
  • Show some actual code of what you've tried. Is this Java 8? if not that's very important. Commented Apr 15, 2017 at 13:37
  • I've only list of data objects of myOwnClass, and used Collection.sort(thatList); Commented Apr 15, 2017 at 13:39
  • 1
    Tip: Use only the java.time classes, never the Date & Calendar classes. Commented Apr 15, 2017 at 18:59

5 Answers 5

3

public boolean before(Date when)

true if and only if the instant of time represented by this Date object is strictly earlier than the instant represented by when; false otherwise.

please refer java docs for more info https://docs.oracle.com/javase/8/docs/api/java/util/Date.html#before-java.util.Date-

Or you can use after method from Date Class inplace of before

package com.stackoverflow.DataSortReverse;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

class Car{
    private String name;
    private Date date;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    public Car(String name, Date date) {
        super();
        this.name = name;
        this.date = date;
    }
    @Override
    public String toString() {
        return "Car [date=" + date + "]";
    }
}

public class DateSort {

    public static void main(String[] args) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<Car> carList = new ArrayList<Car>();
        try {
            carList.add(new Car("car1",dateFormat.parse("2017-01-10")));
            carList.add(new Car("car1",dateFormat.parse("2017-02-10")));
            carList.add(new Car("car1",dateFormat.parse("2017-02-30")));
            carList.add(new Car("car1",dateFormat.parse("2017-01-09")));
        } catch (ParseException e) {
            System.out.println(e.getMessage());
        }
        /*
         * if you wish to change sorting order just 
         * replace -1 with 1 and 1 with -1
         * 
         * 
         * date1.before(date2)  returns true when date1 comes before date2 
         * in calendar
         * 
         * java docs :: https://docs.oracle.com/javase/8/docs/api/java/util/Date.html#before-java.util.Date-
         * */
        Collections.sort(carList, new Comparator<Car>() {
            @Override
            public int compare(Car o1, Car o2) {
                if(o1.getDate().before(o2.getDate())){
                    return -1;
                }
                return 1;
            }
        });
        System.out.println(carList);
    }

}
Sign up to request clarification or add additional context in comments.

Comments

2

Can you try that. I think it will work:

SimpleDateFormat f = new SimpleDateFormat("YYYY-MM-DD HH:mm");
        Stream<Date> sorted = l.stream().map(a->{
            try {
                return f.parse(a);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }).sorted();

UPDATE: and if you want a list:

List sorted = l.stream().map(a->{
            try {
                return f.parse(a);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }).sorted().collect(Collectors.toList());

UPDATED: (as question updated using "cars")

SimpleDateFormat f = new SimpleDateFormat("YYYY-MM-DD HH:mm");
        List<Car> sorted = cars.stream().sorted(
                (a,b)->
        {
            try {
                return f.parse(a.getDate()).compareTo(f.parse(b.getDate()));
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return 0;
        }
        ).collect(Collectors.toList());

4 Comments

it would be much clearer without that ParseException...:| but its throwing it so we have to deal with it
And where I've to put my list of objects, is it this L (lowerCase) ?
I implemented it for your list "cars"
It works thanks!!!!
2

If you are using java 8:

 DateTimeFormatter fm = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
 objects.sort((o1, o2) -> LocalDateTime.parse(o1.getDateStr(), fm)
                    .compareTo(LocalDateTime.parse(o2.getDateStr(), fm)));

And java 7:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Collections.sort(objects, new Comparator<YourObjectType>() {
            public int compare(YourObjectType o1, YourObjectType o2) {
                try {
                    return df.parse(o1.getDateStr()).compareTo(df.parse(o2.getDateStr()));
                } catch(ParseException pe) {
                    // handle the way you want...
                }
        }
    });

Comments

1

Clean solution without ParseException:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
list.sort(Comparator.comparing(shop -> LocalDateTime.parse(shop.getDate(), formatter)));

5 Comments

It shows me an error: Exception in thread "main" java.time.format.DateTimeParseException: Text '2017-04-02' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2017-04-02 of type java.time.format.Parsed
so its better without the exception, but not without the exception handling :D
@stackish I think, this is because some of your dates do not contain the time part (e.g. 2017-04-02 instead of 2017-04-02 12:00).
I've change all my dates to format "YYYY-MM-DD" without hours and still give me exceptions
@stackish Use "yyyy-MM-dd". YYYY and DD mean a bit different things.
-1

A revision of my solution. If you define the following comparator class...

class ShopDateComparator implements Comparator<Shop> {
  @Override
  public int compare(Shop shop1, Shop shop2) {
    return shop1.getDate().toLowerCase().compareTo(shop2.getDate().toLowerCase());
  }
}

...then all you need to do sort cars (which I’m assuming is a list of objects of type Shop) is:

Collections.sort(cars, new ShopDateComparator());

6 Comments

but I've a List<Shop> cars , and inside it I've a date as string in format "YYYY-MM-DD" and i'd like to sort by this date
My answer was just a guide, and the solution specific to your code would be quite similar: Collections.sort(cars, (Shop shop1, Shop shop2) -> shop1.date.toLowerCase().compareTo(shop2.date.toLowerCase()));
It doesn't work, i've tried your solution
I’ve revised my answer — check it out and see if it works for you.
@JoeydeVilla The .toLowerCase() are actually not needed, because the strings don't contain any letters, only 0123456789:- according to the used date-time format.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.