1

Input is a list containing date in String format. I have solution as below. But i feel it can be made more efficient. Any help would be appreciated.

//Map to store month data

HashMap<String,String> month = new HashMap<String,String>();
        month.put("Jan","01");
        month.put("Feb","02");
        month.put("Mar","03");
        month.put("Apr","04");
        month.put("May","05");
        month.put("Jun","06");
        month.put("Jul","07");
        month.put("Aug","08");
        month.put("Sep","09");
        month.put("Oct","10");
        month.put("Nov","11");
        month.put("Dec","12");

You can consider this as input

    String[] input = {"20 Oct 2052",
    "26 May 1960",
    "06 Jun 1933",
    "06 Jun 1933",
    "06 Jun 1933",
};


    ArrayList<Long> temp1 = new ArrayList<Long>();

To compare result

    HashMap<Long,String> temp2 = new HashMap<Long,String>();

    ArrayList<String> result = new ArrayList<String>();
    for(int i = 0 ; i< input.length ; i++){
        String j = "";
        if(input[i].length() == 11){

            j+= input[i].substring(7,11);
            j+= month.get(input[i].substring(3,6));
            j+=input[i].substring(0,2);

            temp1.add(Long.parseLong(j));
            temp2.put(Long.parseLong(j), input[i]);   
        }
    }

Sorting the result

Collections.sort(temp1);

Printing the result

System.out.println(temp1.toString());
heyitsvajid
  • 1,023
  • 1
  • 10
  • 19
  • I think **PriorityQueue** would be helpful in this case – suvojit_007 Oct 12 '18 at 07:37
  • Possible duplicate of [How to sort Date which is in string format in java?](https://stackoverflow.com/questions/14451976/how-to-sort-date-which-is-in-string-format-in-java) – Ole V.V. Oct 12 '18 at 08:02
  • I wrote [a new answer to the linked original question](https://stackoverflow.com/a/52776978/5772882). Instead of `LocalDateTime` as in that answer use `LocalDate` (since your dates don’t have time of day), and use a `DateTimeFormatter.ofPattern("dd MMM uuuu", Locale.ENGLISH)`. That should give you the effective and efficient solution. – Ole V.V. Oct 12 '18 at 09:58

5 Answers5

2

Radix Sort is your friend. Just sort strings with this algorithm. This is optimal solution.

Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
2

Firstly I would parse the date strings into a Date Object

DateFormat format = new SimpleDateFormat("dd MMM yyyy", Locale.ENGLISH);
Date date = format.parse("26 May 1960");

You could create an object that holds a Date object then make it comparable.

public class DateContainer implements Comparable<DateContainer > {
 private Date dateTime;

 public DateContainer (Date date){
  this.dateTime = date;
 }

 public Date getDateTime() {
  return dateTime;
 }

 public void setDateTime(Date datetime) {
  this.dateTime = datetime;
 }

 @Override
 public int compareTo(DateContainer o) {
   return getDateTime().compareTo(o.getDateTime());
 }
}

Then you could create a list of the Object above then use Collections to sort it

Collections.sort(myList);
Joseph McCarthy
  • 305
  • 2
  • 7
  • 1
    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. Oct 12 '18 at 08:01
  • So that's true, there are better implementations. But for the purpose of this question when they are just using Strings, anything solution is a better solution. – Joseph McCarthy Oct 12 '18 at 08:20
1
public static void main(String[] args) {
    SimpleDateFormat f = new SimpleDateFormat("dd MMM yyyy");
    String[] input = {"20 Oct 2052",
            "26 May 1960",
            "06 Jun 1933",
            "06 Jun 1933",
            "06 Jun 1933",
    };
    Map<Long, String> result = new TreeMap<>();
    Stream.of(input)
            .filter(s -> s.length() == 11)
            .forEach(s -> {
                try {
                    result.put(f.parse(s).getTime(), s);
                } catch (ParseException e) {
                    System.out.println("Wrong Format: " + s);
                }
            });
    System.out.println(result); // {-1154156400000=06 Jun 1933, -303033600000=26 May 1960, 2612970000000=20 Oct 2052}
}

Use SimpleDateFormat to get Date value and TreeMap to sorted elements in the map.

Hope that help you!!!!

  • 2
    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. Oct 12 '18 at 08:01
1

This should do the trick

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMM yyyy");

List<Date> dates = Arrays.stream(input).map(dateString -> {
try {
    return simpleDateFormat.parse(dateString);
} catch (ParseException e) {
    e.printStackTrace();
}
    return null;
}).collect(Collectors.toList());
dates.sort(Comparator.naturalOrder());

dates.forEach(date -> System.out.println(simpleDateFormat.format(date)));

this is a 2 step process

  1. Convert to java.util.Date
  2. Sort the Date list and Print

Hope this helps!

Good luck!

Vihar
  • 3,626
  • 2
  • 24
  • 47
  • 1
    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. Oct 12 '18 at 08:01
1

tl;dr

This is a one-liner using modern java.time classes and lambda syntax.

Parse each string into a LocalDate, collect, sort, and regenerate strings as output.

Arrays.stream(
        new String[] { "20 Oct 2052" , "26 May 1960" , "06 Jun 1933" , "06 Jun 1933" , "06 Jun 1933" }
)
        .map( input -> LocalDate.parse( input , DateTimeFormatter.ofPattern( "dd MMM uuuu" , Locale.US ) ) )
        .sorted()
        .map( date -> date.format( DateTimeFormatter.ofPattern( "dd MMM uuuu" , Locale.US ) ) )
        .collect( Collectors.toList() )
        .toString()

[06 Jun 1933, 06 Jun 1933, 06 Jun 1933, 26 May 1960, 20 Oct 2052]

Steps:

  • Generate a stream of your array's elements (the string inputs).
  • Process each input, parsing to get a LocalDate
  • Sort the LocalDate objects
  • On each LocalDate, generate text representing its value.
  • Collect each of those generated strings into a List.
  • Generate text representing the list of strings, now sorted in chronological order.

Smart objects, not dumb strings

Use appropriate data types rather than mere strings.

For a date-only value without time-of-day and without time zone, use LocalDate class.

Define a formatting pattern to match your inputs.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd MMM uuuu" , Locale.US );

Loop the inputs, parsing each into a LocalDate. Collect each resulting LocalDate into a List.

    List < LocalDate > dates = new ArrayList <>( inputs.length );
    for ( String input : inputs ) {
        LocalDate ld = LocalDate.parse( input , f );
        dates.add( ld );
    }

Or instead, use the short and sweet lambda syntax.

List < LocalDate > dates = Arrays.stream( inputs ).map( input -> LocalDate.parse( input , f ) ).collect( Collectors.toList() );

Sort the list of LocalDate objects.

Collections.sort( dates );

Report your sorted dates in standard ISO 8601 format.

String outputs = dates.toString() ;

[1933-06-06, 1933-06-06, 1933-06-06, 1960-05-26, 2052-10-20]

Report your sorted dates in any desired format.

   List < String > outputs = new ArrayList <>( dates.size() );
    for ( LocalDate date : dates ) {
        outputs.add( date.format( f ) );
    }

[06 Jun 1933, 06 Jun 1933, 06 Jun 1933, 26 May 1960, 20 Oct 2052]


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154