Sorting arrays different ways in Java - java

I have a map(String, LinkedList) mp. This corresponds to a table like this:
Name Date Dept
Tony 4/1/2014 55125
Bob 3/2/2013 54112
Jill 7/2/2014 55265
(I just made these up for this example. The first row (Name, Date, Dept) are the headings and correspond to the key value in the map (so you do an mp.get("Name") for example). The linked list that is returned for Name is , for Date is <4/1/2014, 3/2/2013, 7/2/2014> and Dept is <55125, 54112, 55265> etc.
I need to get the list for a value and then sort it. For Name and Dept I believe I can just do a Collections.sort(), but this will not work for date. If date was yyyymmdd it would work, but date is mm/dd/yyyy which is not guaranteed to sort correctly, and usually won't. I suppose I could process each entry and change it to yyyymmdd, but some of the fields will be blank (or maybe null but I think blank).
I can easily determine when to sort normally and when by date. Just not sure how to use Collections.sort() or something else to sort the date list. Can anyone help?

The Collections.Sort method allows you to (optionally) specify your own Comparator. In your case, when you sort the date column you will need to provide your own comparator.
If you are using Java 8 then the code will look something like this:
Collections.sort(dataMap.get("Date"), (date1, date2) -> compareDates(date1, date2));
The compareDates method would then need to be able to handle nulls and would need to pull apart the date components and return number of days from date1 to date2. You could easily use the java.util.Date object to do that - just convert the dates (possibly using DataFormat) and then compare.

Related

To make sure the dates in the webtable are already sorted

I have one column in the webtable which contains dates (they are already sorted from latest to older).
Now my test case is to prove that dates are already sorted in the webtable.
By this code I will get all the dates to the list variable:
List<WebElement> rows = driver.findElements(By.xpath("//*[#id='ui-datepicker-div']/div[1]/table/tbody/tr/td[1]"));
How I can prove this list is sorted and displayed in the UI?
List<WebElement> rows = driver.findElements(By.xpath("//*[#id='ui-datepicker-div']/div[1]/table/tbody/tr/td[1]"));
You can proceed ahead to split the problem and solve somewhat like this. This is just a method of doing it, ideally, would expect you to write code for it:
You have a List<WebElement> rows and you need to construct a List<String> dates from it. Iterate over the rows and do a .getText() to add to the dates.
Create a method compareDates(String d1, String d2) that given two string dates compares in whatever format it is in your UI and returns 0,1,-1 as a compareTo method does.
Iterate over the newly created list dates as in (1) and then assert adjacent comparisons
Assertion.assertTrue(compareDates(dates.get(i),dates.get(i+1)) == 0);
Note: The above operations can be done on a List<Date> instead of List<String> as well where in you can use the java built-in comparison methods to compare two dates. Thanks to #JeffC for pointing this out in comments.

Better data structure for retrieving data in between dates

I have a class which stores a date as the key and a price as the value. My data structures stores about 5M entries. When I want to retrieve the data which are in a certain date range, I will loop through the data structure and check if the current data is within the date range.
e.g.
if (startDate >= data.date && data.date <= endDate)
//do something
However, this is extremely inefficient. Is there a better way to do this?
If memory/performance is not a constraint*, you could simply use a TreeMap, which has a subMap method that allows you to filter on a time window:
TreeMap<Date, Double> data = ...;
for (Double price : data.subMap(startDate, true, endDate, true).values()) {
//do something with price
}
*i.e. if you don't need to keep the prices as primitive doubles for example
Make sure that the data is ordered by the key (i.e. by the date).
Use binary search to find the start date
Enumerate as long as you haven't reached the end date
Voila
Edit: Yup, using a TreeMap automates the job pretty well. Don't know if you are allowed to change your data structure.

Good ways to sort a sortedset when data is string date

The Sortedset can sort itself automatically but in some case, it doesn't work as I want. For example. I stored String date value in a sortedset but apparently it didn't work as my expectation. This is what I got:
[03-10-2013, 06-10-2013, 08-10-2013, 09-10-2013, 18-09-2013, 24-09-2013, 29-09-2013]
Is there any good way to deal with this problem without having to introduce a comparator?
The best way is to avoid using String to represent a Date. Use a Date, which has a natural chronological order. Transform the date to a String only when necessary, i.e. to display it to users or store them in files.
The reason it doesn't work is that the natural ordering of String is the lexicographic order. So "18-09-2013" comes after "03-10-2013", simply because '1' comes after '0' in the lexicographic order.
Use a set of either:
Date objects java.util.Date or
Time in milli seconds java.lang.Integer
These objects can be compared much easier.

HashMap<DateTime, ArrayList<Email>>

I work on a graph where I visualize my emails. I want to be able to get the emails from a certain day.
Is this a bad way to store?
HashMap<DateTime, ArrayList<Email>>
Or is it better to convert the date to a string and then use HashMap<String, ArrayList<Email>>
Note, the dates are added without hours, minutes and seconds, so just like 06/07/2010 for example.
DateTime has properly defined equals and hashcode methods, so using those as the key in a HashMap is perfectly OK. There's not much to be gained by converting them to strings first.
I would suggest, however, that if you only want to store the year/month/day components, then you may want to use LocalDate instead of DateTime.
Additionally, you could also consider using TreeMap rather than HashMap, so that your map is automatically sorted by date. Might be handy.

I need data structure for effective handling with dates

What I need is something like Hashtable which I will fill with prices that were actual at desired days.
For example: I will put two prices: January 1st: 100USD, March 5th: 89USD.
If I search my hashtable for price: hashtable.get(February 14th) I need it to give me back actual price which was entered at Jan. 1st because this is the last actual price. Normal hashtable implementation won't give me back anything, since there is nothing put on that dat.
I need to see if there is such implementation which can find quickly object based on range of dates.
Off the top of my head, there are a couple ways, but I would use a TreeMap<Date> (or Calendar, etc).
When you need to pull out a Date date, try the following:
Attempt to get(date)
If the result is null, then the result is in headMap(date).lastKey()
One of those will work. Of course, check the size of headMap(date) first because lastKey() will throw an Exception if it is empty.
You could use a DatePrice object that contains both and keep those in a list or array sorte by date, then use binary search (available in the Collections and Arrays classes) to find the nearest date.
This would be significantly more memory-effective than using TreeMap, and it doesn't look like you'll want to insert or remove data randomly (which would lead to bad performance with a array).
Create a Tree Map with Date,String. If some one calls for a date then convert the string to date and call map.get(date), if you find then take the previous key than the current element.
You have all your tools already at hand. Consider a TreeMap. Then you can create a headmap, that contains only the portion of the map that is strictly lower that a given value. Implementation example:
TreeMap<Date,Double> values = new TreeMap<Date,Double>();
...fill in stuff...
Date searchDate = ...anydate...
// Needed due to the strictly less contraint:
Date mapContraintDate = new Date(searchDate.getTime()+1);
Double searchedValue = values.get(values.headMap(mapContraintData).lastKey);
This is efficient, because the headMap is not create by copying the original map, but returns only a view.

Categories