1

I have declared a ArrayList as follows:

ArrayList<HashMap<String, String>> oslist = new ArrayList<HashMap<String, String>>();

Each element of oslist contains 5 Hashmaps:

            HashMap<String, String> map = new HashMap<String, String>();
            map.put(string, string);
map.put(string, string);
map.put(string, string);
map.put(string, string);
map.put(string, string);

One of these is the date in following format: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

Now I have written this class which sorts this date format. Class and its usage are as follows:

DateObject.java

package com.test;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class DateObject implements Comparable<Object> {

    private String date;
    private String time;

    public DateObject(String dates) {
        try {
            Date date_for = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
                    Locale.ENGLISH).parse(dates);
            String date_upd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH)
            .format(date_for);
            //System.out.println(date_upd);
            String[] parts = date_upd.split(" ");
            this.date = parts[0]; 
            this.time = parts[1];
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public int compareTo(Object o) {

        DateFormat formatter;
        Date date1 = null;
        Date date2 = null;
        formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            date1 = (Date) formatter.parse(this.date + " " + this.time);
            DateObject other = (DateObject) o;
            date2 = (Date) formatter.parse(other.date + " " + other.time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        catch(NullPointerException npe){
            System.out.println("Exception thrown "+npe.getMessage()+" date1 is "+date1+" date2 is "+date2);
        }

        return date2.compareTo(date1);

    }

    @Override
    public String toString(){       
        return this.date+" "+this.time;
    }

}

Test.java

package com.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


    public class Test {

        public static void main(String[] args) {

               List<DateObject> list = new ArrayList<DateObject>();
    ;

                DateObject d1 = new DateObject("2012-12-05T11:20:19.111Z");
                list.add(d1);

                d1 = new DateObject("2012-12-05T11:20:19.111Z");
                list.add(d1);

                d1 = new DateObject("2012-12-04T10:20:19.111Z");
                list.add(d1);

                d1 = new DateObject("2010-12-07T13:20:19.111Z");
                list.add(d1);

                d1 = new DateObject("2012-12-05T11:20:19.111Z");
                list.add(d1);
                Collections.sort(list);

                for(DateObject d : list){
                    System.out.println(d);
                }

        }
    //  "yyyy-MM-dd HH:mm:ss
    }

My question is how can I use this class to sort my oslist? That is when I sort oslist on the basis of date HashMap my other HashMaps also gets sorted out correspondingly. One thing to note is in oslist date will be stored as String so I can't use sort directly. Thanks.

rishiag
  • 2,248
  • 9
  • 32
  • 57
  • 1
    you have 'Map' in oslist. so you have to create comparator for Map. get Date from Map compare them – Adi Aug 26 '14 at 12:21
  • 2
    If you need an ordered map, use a TreeMap instead of HashMap. – EpicPandaForce Aug 26 '14 at 12:23
  • 2
    You're suffering from objectphobia and typephobia. Define your own class (let's say it's called `Foo`), containing correctly typed fields, a. A Date should not be stored as a String, but as a Date. Then use a `List` instead of a `List>`. – JB Nizet Aug 26 '14 at 12:25
  • " Each element of oslist contains 5 Hashmaps"? This is a nonsense statement. Each element of a `List>` is a `HashMap`, which cannot contain _any_ hashmaps. – AJMansfield Aug 26 '14 at 17:11
  • @AJMansfield It's ArrayList not List. – rishiag Aug 26 '14 at 17:17
  • @rishiag There you are wrong: an `ArrayList` _is a_ `List`. Though it would also be correct to say that "each element of an `ArrayList>` is a `HashMap`". – AJMansfield Aug 26 '14 at 17:23

4 Answers4

1

Your Comparable implementation is false, it should be:

public class DateObject implements Comparable<DateObject> {
  ...
  @Override
  public int compareTo(DateObject o) {
     ...
  }
}

And if you want to sort out the map entries, which are by default not Comparable, you must use a specific Comparator:

Collections.sort(oslist.entrySet(), new Comparator<Map.Entry<String,String>>() {
  ...  
});

But I can't recommend you to do it or not since I don't know what you map holds (all are String ?!).

A TreeMap could also prove useful, as it sort by keys.

NoDataFound
  • 11,381
  • 33
  • 59
0

Not sure if I understand the quesion correctly... You want to sort list of hashmaps, and in each hashmap you have a entry with this DateObject? If so you can use java.util.Collections.sort

Collections.sort(listOfHashMaps, new Comparator<HashMap>() {

    @Override
    public int compare(final HashMapo1, final HashMap o2) {
        final String dateObject1 = o1.get("dateObjectKey");
        final String dateObject2 = o2.get("dateObjectKey");
        //parse the date objects compare and return result...
    }

})
Nadir
  • 1,369
  • 1
  • 15
  • 28
0

If you need to sort a list of maps of objects, then you need to write a comparator for how you want to compare a map of objects with another

    ArrayList<HashMap<String, String>> oslist = new ArrayList<HashMap<String, String>>();
    Collections.sort(oslist, new Comparator<HashMap<String, String>>(){

        @Override
        public int compare(HashMap<String, String> o1, HashMap<String, String> o2) {
            //implement your sorting logic here
        };

    });

There's no intrinsic order between two HashMaps. Neither between two TreeMaps (although objects inside a TreeMap, if there's a way to compare them each other, they'll be sorted).

You can reuse your Comparable DateObject inside this function, but remember that you ALSO have to say to Collections.sort() how do you want to compare one HashMap with another.

Leo
  • 6,480
  • 4
  • 37
  • 52
0

The TreeSet has a natural sort by a custom "Comparator" so the String's compareTo() is not used, but you can not add a null-value and not duplicate values (but values with comperae=0).

Ie

public class StringTypeDateTimeComparator extends Comparable<String>{
   public int compare(String o1, String o2){
     return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(o1)
        .compareTo(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(o2));
   }
}

TreeSet<String> ts = new TreeSet<String>(new StringTypeDateTimeComparator());
ts.add("2012-12-01T11:20:19.111Z");
ts.add("2012-12-20T11:20:19.111Z");

Why do i instanciate the SimpleDateFormat twice? Its not Thread-Save.

Grim
  • 1,938
  • 10
  • 56
  • 123
  • The fact that it's not thread-safe doesn't prevent to create it, assign it to a local variable and use it inside your method. Two threads can't share an object referenced only by a local variable. BTW, a TreeSet itself is not thread-safe, and the comparator is part of its state, so you could use a single instance of your date format. It wouldn't make the TreeSet less thread-safe. – JB Nizet Aug 26 '14 at 12:41