I have an ArrayList which contains dates with a format (Satuday,4 Februray 2012). How can I sort this ArrayList ?
This is one of the Simplest way to sort,
Collections.sort(<Your Array List>);
If you have any special requirements while sorting, so you may do it by providing your own Comparator. For example:
//your List
ArrayList<Date> d = new ArrayList<Date>();
//Sorting
Collections.sort(d, new Comparator<Date>() {
#Override
public int compare(Date lhs, Date rhs) {
if (lhs.getTime() < rhs.getTime())
return -1;
else if (lhs.getTime() == rhs.getTime())
return 0;
else
return 1;
}
});
The key element is that you are converting your Date object into milliseconds (using getTime()) for comparison.
After 8 years..
List<Date> dates = datelist;
List<Date> sorted = dates.stream()
.sorted(Comparator.comparingLong(Date::getTime))
.collect(Collectors.toList());
Related
...
public class DateLimiter {
private Date startDate;
private Date endDate;
}
List<DateLimiter> period = new ArrayList<>();
period.add(1/1/2020, 31/1/2020);
period.add(1/2/2020, 29/2/2020);
period.add(1/3/2020, 1/5/2020);
period.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
...
How to use java 8 (LAMBDA) to check the collection if all the periods object are continuous periods
for example endDate+1 "day" should be equals to the next period startDate
You are doing a number of things incorrectly or not at all.
Trying to add a non-string to an ArrayList that only takes DateLimiter objects.
Trying to add two elements to an ArrayList with add.
Not creating instances of DateLimiter.
You should also be using LocalDate and not Date.
Given that you must use java.util.Date and the list is sorted, you can use the function below.
public boolean isCorrect(ArrayList<DateLimiter> list) {
for (int i = 1; i < list.size(); i++) {
Date prevEndDate = list.get(i - 1).getEndDate();
Date currStartDate = list.get(i).getStartDate();
Calendar cal = Calendar.getInstance();
cal.setTime(prevEndDate);
cal.add(Calendar.DAY_OF_MONTH, 1);
if (cal.getTime().equals(currStartDate)) {
return false;
}
}
return true;
}
I have a list of objects that have as a member a iso 8601 UTC string.
I would like to sort the list in descending order.
The following works:
Collections.sort(myList, (o1, o2) -> { o2.getDate().compare(o1.getDate()) } );
the function getDate() is implemented as follows:
public DateTime getDate() {
return new DateTime(isoUtcString);
}
I am not sure if instantiating the DateTime each time is the best way. Also I know I could use millis as well. Eg. I could have
long utcMillis = new DateTime(isoUtcString).getMillis();
As variable of the class and do
Collections.sort(myList, (o1, o2) -> {
if(o1.getUtcEpoch() > o2.getUtcEpoch()) {
return -1; //reverse order
}
else if(o1.getUtcEpoch < o2.o1.getUtcEpoch) {
return 1; //reverse order
}
return 0;
} );
And the getUtcEpoch() is
long getUtcEpoch() {
return utcMillis;
}
So my question is, should I stick to Date classes for sorting or using UTC millis is a better alternative?
Is there any way to return two values from one method....
Example:
public Class Sample
{
public List<Date> returnTwoArrayList()
{
List<Date> startDate=new ArrayList<Date>();
List<Date> endDate=new ArrayList<Date>();
//So I want to Return Two values startDate and endDate ...It is Possible????
}
}
i'm calling this method into My Service class and in that Storing StartDate and endDate into Database here these are Two different Columns
**StartDate endDate**
2012-12-01 2012-12-05
2012-12-01 2012-12-15
2012-12-02 2012-12-10
2012-12-20 2012-12-25
2012-12-25 2012-12-31
You cannot return separate structures via one method call, but you can return a composite of them. For example, returning a list of your lists would be a possible solution:
public List<List<Date>> returnTwoArrayList()
{
List<Date> startDates = new ArrayList<Date>();
List<Date> endDates = new ArrayList<Date>();
List<List<Date>> result = new ArrayList<List<Date>>();
result.add(startDates);
result.add(endDates);
return result;
}
You can use get() method to retrieve these lists later on.
Suppose you have made a call like List<List<Date>> twoLists = returnTwoArrayList(); then
you can get startDate by calling twoLists.get(0) and similarly endDate with twoLists.get(1)
No you can not return two value from a method.
Best way would be create a custom class with two field and return that object.
class ObjectHolder{
private List<Date> startDate=new ArrayList<Date>();
private List<Date> endDate=new ArrayList<Date>();
<getter & setter method>
}
and -
public ObjectHolder returnTwoArrayList(){
ObjectHolder oh = new ObjectHolder();
List<Date> startDate=new ArrayList<Date>();
oh.setStartDate(startDate);
List<Date> endDate=new ArrayList<Date>();
oh.setEndDate(endDate);
return oh;
}
You can
provide one or both lists as argument(s) to populate.
have two lists which are fields of the instance of the method and access these via getters.
return an array of two lists or a list of lists.
return a custom type which wrap the two lists. I wouldn't use getters, just makes the fields public.
have a single list of intervals
I believe the last is the best solution.
public class Sample {
public List<Interval> returnListOfStartToEndDates() {
List<Interval> intervals=new ArrayList<>();
return intervals;
}
}
Joda-time has an Interval class which is more efficient than creating two Date objects, but you can also create your own.
You could create a custom class like this
TimeSpan(ArrayList<Date> startDate, ArrayList<Date> endDate)
and return that Object.
Directly, no, unless you count returning an array of two Lists, or a List of Lists with the stated understanding to the caller that it would contain exactly two entries and what value each one would represent.
Other than that, you could always write a Pair class and use that, which would be better because it removes the dependence on that assumption about the dimension of the return value, and you will find that a Pair type comes in handy in many, many situations.
Instead you can use Map like the following,
public Map<String, List<Date>> getBothDates() {
List<Date> startDate = new ArrayList<Date>();
List<Date> endDate = new ArrayList<Date>();
Map<String, List<Date>> bothDates = new HashMap<String, List<Date>>();
bothDates.put("startDate", startDate);
bothDates.put("endDate", endDate);
return bothDates;
}
To fetch both dates simple iterate the map,
public void printBothDates() {
Map<String, List<Date>> bothDates = getBothDates();
for(Entry<String, List<Date>> entry : bothDates.entrySet()) {
if(StringUtils.equalsIgnoreCase("startDate", entry.getKey())) {
for(Date d : entry.getValue()) {
System.out.println("startDate---"+d);
}
} else if(StringUtils.equalsIgnoreCase("endDate", entry.getKey())) {
for(Date d : entry.getValue()) {
System.out.println("endDate---"+d);
}
}
}
}
import java.util.ArrayList;
public class MyClass {
public ArrayList<ArrayList> TwoArrayList() {
ArrayList cars = new ArrayList();
cars.add("Volvo");
cars.add("BMW");
cars.add("Ford");
cars.add("Mazda");
ArrayList fruits = new ArrayList();
fruits.add("Apple");
fruits.add("Mango");
fruits.add("Banana");
fruits.add("Orange");
ArrayList <ArrayList> twoArrayList = new ArrayList <ArrayList>();
twoArrayList.add(cars);
twoArrayList.add(fruits);
return twoArrayList;
}
public static void main(String[] args) {
MyClass obj = new MyClass();
ArrayList <ArrayList> Arlist= obj.TwoArrayList();
System.out.println(Arlist.get(0));/**FIRST ARRAY LIST*/
System.out.println(Arlist.get(0).get(0));/**FIRST ARRAY LIST FIRST Element*/
System.out.println(Arlist.get(1));/**SECOND ARRAY LIST*/
System.out.println(Arlist.get(1).get(0));/**SECOND ARRAY LIST FIRST Element*/
}
}
OUTPUT IS HERE
enter image description here
I have an Array of Hashmap and each hashmap contain 24 hour time as key-value pair.
I want to sort this array in ascending order of time. how can i achieve this?
here is snippet of my code:
HashMap[] arr = new HashMap[100];
for(int i=0;i<100;i++) {
HashMap<String,String> child=new HashMap<String,String>();
child.put("some_time","21:09"); //time changes per iteration(time is in 24-hour format)
arr[i]=child;
}
Here is the full code that will sort the array on time which is in hh:mm format:
HashMap<String,String>[] harr = new HashMap[10];
final DateFormat df = new SimpleDateFormat("kk:mm");
// prepare your data
for(int i=0;i<harr.length;i++) {
HashMap<String,String> child=new HashMap<String,String>();
int ss = (int)(Math.random() * (59 + 1));
//time changes per iteration(time is in 24-hour format)
child.put("some_time", String.format("21:%02d", ss));
harr[i]=child;
}
System.out.printf("map array is: %s%n", Arrays.deepToString(harr));
// now apply sort using a custom method
Arrays.sort(harr, new Comparator<HashMap<String,String>>() {
public int compare(HashMap<String,String> o1, HashMap<String,String> o2) {
String t1 = o1.get("some_time");
String t2 = o2.get("some_time");
try {
Date dt1 = df.parse(t1);
Date dt2 = df.parse(t2);
return dt1.compareTo(dt2);
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}
});
System.out.printf("sorted map array is: %s%n", Arrays.deepToString(harr));
You can use Arrays.sort(T[], Comparator<T>). This allows you to pass an array of any type and write your own custom comparator method like this:
Arrays.sort(arr, new Comparator<HashMap>() {
public int compare(HashMap o1, HashMap o2) {
// Compare values you're interested in and return int as specified by Comparator API
}
});
See the API for details on what to return.
Before proceeding with this approach, do think about the comments and decide whether the array of hashmaps is the right way to go. If, as I pointed out, you have a bunch of maps, each containing large amounts of information, with one entry being your dates, then this may be the right thing to do, in which case the easiest way to sort the array would be to use Arrays.sort method:
HashMap[] arr=new Hashmap[100];
for(int i=0;i<100;i++){
HashMap<String,String> child=new HashMap<String,String>();
... // put all the info into the HashMap
child.put("some_time","21:09"); //time changes per iteration(time is in 24-hour format)
arr[i]=child;
}
Arrays.sort(arr, new Comparator<HashMap>() {
public int compare(HashMap o1, HashMap o2) {
String d1 = o1.get("some_time");
String d2 = o2.get("some_time");
//compare the two dates. If you're always in the same format, e.g. HH:MM (24 hours, two-digit hour, two-digit year), you might even be able to simply compare strings:
return d1.compareTo(d2);
}
});
The general approach is to write a Comparator to order a pair of your HashMap objects based on the key, and then pass that as a parameter to the Arrays.sort(T[], Comparator<T>) method.
Th comparator would look something like this:
Comparator<HashMap> DATE_ORDER = new Comparator<HashMap>() {
public int compare(Comparator<HashMap>h1, Comparator<HashMap>h2) {
String time1 = h1.get("some_time");
String time2 = h2.get("some_time");
return time1.compareTo(time2); // assuming that the time strings
// can be ordered that way
}
};
Having said that, your problem has the "smell" of trying to use Maps when they should really be writing custom classes.
As Bhavik points out, you may not be using the JDK to it's full potential - have a look at SortedMap which may be just what you're looking for; possibly with your own implementation of a Comparator.
SortedMap arr = new TreeMap<String,HashMap<String,String>>();
for ( int i=0 ; i<100 ; i++ )
{
Map<String,String> child = HashMap<String,String>();
child.put( "some_time" , "21:09" );
arr.put( "21:09" , child );
}
then you can use arr.values().iterator() to get your sorted children.
Cheers,
Collections.sort(someList, new Comparator<SomeObject>() {
public int compare(final SomeObject object1, final SomeObject object2) {
return (object1.getSomeDate()).compareTo(object2.getSomeDate());
}}
);
Would it give me the objects with latest dates meaning the list will contain the set of objects with latest date to oldest date?
Comparator.comparing
You can pass a method reference to Comparator.comparing.
If you want the objects to be sorted in ascending order based on the date:
someList.sort(Comparator.comparing(SomeObject::getSomeDate));
or
someList.sort(Comparator.comparing(SomeObject::getSomeDate).reversed());
for descending order.
To be sure you can use:
Collections.sort(someList, new Comparator<SomeObject>() {
public int compare(final SomeObject object1, final SomeObject object2) {
return object1.getSomeDate().after(object2.getSomeDate()) ? 1 : -1;
}}
);
The default ordering of Date will put newer dates after older dates so the oldest dates would be at the beginning of your list and the newest dates at the end. Comparators have always been hard to read in my opinion so I have switched to using google's Ordering objects that implement Comparator a little cleaner. For example your Comparator could be written like this:
Ordering<SomeObject> order = Ordering.natural().onResultOf(new Function<SomeObject, Date>() {
public Date apply(SomeObject object) {
return object.getDate();
}
});
Comparator<SomeObject> comparator = order; // Ordering implements Comparable so this would be legal to do
Collections.sort(someList, order);
The order Comparator that this code created would sort SomeObject objects based on their Date using the Date's natural ordering. But what makes Ordering really nice is some of extra methods change the order without having to write any more logic, for example to reverse the order of dates to be newest to oldest you just have to add a call to reverse():
Ordering<SomeObject> order = Ordering.natural().reverse().onResultOf(new Function<SomeObject, Date>() {
public Date apply(SomeObject object) {
return object.getDate();
}
});
This is old but may be someone can use it. It may be sorted using java8 as follows:
someList.sort(Comparator.comparing(listMember::dateProducingMethod))
By using lambdaj you could achieve the same result in an easier and more readable way as it follows:
sort(someList, on(SomeObject.class).getSomeDate());
Far better than writing an obscure inner class, isn't it?
Try this:
List<Date> list=new ArrayList<Date>();
//add some dates to list
Collections.sort(list, new Comparator<Date>() {
public int compare(final Date object1, final Date object2) {
return Long.compare(object1.getTime(),object2.getTime());
}}
);
Date.getTime() "converts" the date to a long, which is easier to compare and sort.
Anyway behind the curtain Longs are compared with this:
public static int compare(long x, long y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
If you want to invert the sort, just multiply by -1 like this:
List<Date> list=new ArrayList<Date>();
//add some dates to list
Collections.sort(list, new Comparator<Date>() {
public int compare(final Date object1, final Date object2) {
return Long.compare(object1.getTime(),object2.getTime())*-1;
}}
);