Arrange a List<String[]> alphabetically [duplicate] - java

I read about sorting ArrayLists using a Comparator but in all of the examples people used compareTo which according to some research is a method for Strings.
I wanted to sort an ArrayList of custom objects by one of their properties: a Date object
(getStartDay()). Normally I compare them by item1.getStartDate().before(item2.getStartDate()) so I was wondering whether I could write something like:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...
}

Since Date implements Comparable, it has a compareTo method just like String does.
So your custom Comparator could look like this:
public class CustomComparator implements Comparator<MyObject> {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
The compare() method must return an int, so you couldn't directly return a boolean like you were planning to anyway.
Your sorting code would be just about like you wrote:
Collections.sort(Database.arrayList, new CustomComparator());
A slightly shorter way to write all this, if you don't need to reuse your comparator, is to write it as an inline anonymous class:
Collections.sort(Database.arrayList, new Comparator<MyObject>() {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
Since java-8
You can now write the last example in a shorter form by using a lambda expression for the Comparator:
Collections.sort(Database.arrayList,
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
And List has a sort(Comparator) method, so you can shorten this even further:
Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
This is such a common idiom that there's a built-in method to generate a Comparator for a class with a Comparable key:
Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));
All of these are equivalent forms.

Classes that has a natural sort order (a class Number, as an example) should implement the Comparable interface, whilst classes that has no natural sort order (a class Chair, as an example) should be provided with a Comparator (or an anonymous Comparator class).
Two examples:
public class Number implements Comparable<Number> {
private int value;
public Number(int value) { this.value = value; }
public int compareTo(Number anotherInstance) {
return this.value - anotherInstance.value;
}
}
public class Chair {
private int weight;
private int height;
public Chair(int weight, int height) {
this.weight = weight;
this.height = height;
}
/* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getWeight() - chair2.getWeight();
}
}
class ChairHeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getHeight() - chair2.getHeight();
}
}
Usage:
List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);
List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());
// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
public int compare(Chair chair1, Chair chair2) {
...
}
});

For sorting an ArrayList you could use the following code snippet:
Collections.sort(studList, new Comparator<Student>(){
public int compare(Student s1, Student s2) {
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
}
});

JAVA 8 lambda expression
Collections.sort(studList, (Student s1, Student s2) ->{
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});
OR
Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)

Yes, you can. There are two options with comparing items, the Comparable interface, and the Comparator interface.
Both of these interfaces allow for different behavior. Comparable allows you to make the object act like you just described Strings (in fact, String implements Comparable). The second, Comparator, allows you to do what you are asking to do. You would do it like this:
Collections.sort(myArrayList, new MyComparator());
That will cause the Collections.sort method to use your comparator for it's sorting mechanism. If the objects in the ArrayList implement comparable, you can instead do something like this:
Collections.sort(myArrayList);
The Collections class contains a number of these useful, common tools.

With Java 8 you can use a method reference for your comparator:
import static java.util.Comparator.comparing;
Collections.sort(list, comparing(MyObject::getStartDate));

Since technologies appear everyday, the answer will change in the time. I took a look at LambdaJ and seems very interesting.
You can try solving these tasks with LambdaJ. You can find it here: http://code.google.com/p/lambdaj/
Here you have an example:
Sort Iterative
List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
}
});
Sort with lambda
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
Of course, having this kind of beauty impacts in the performance (an average of 2 times), but can you find a more readable code?

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
public class test {
public static class Person {
public String name;
public int id;
public Date hireDate;
public Person(String iname, int iid, Date ihireDate) {
name = iname;
id = iid;
hireDate = ihireDate;
}
public String toString() {
return name + " " + id + " " + hireDate.toString();
}
// Comparator
public static class CompId implements Comparator<Person> {
#Override
public int compare(Person arg0, Person arg1) {
return arg0.id - arg1.id;
}
}
public static class CompDate implements Comparator<Person> {
private int mod = 1;
public CompDate(boolean desc) {
if (desc) mod =-1;
}
#Override
public int compare(Person arg0, Person arg1) {
return mod*arg0.hireDate.compareTo(arg1.hireDate);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
ArrayList<Person> people;
people = new ArrayList<Person>();
try {
people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Collections.sort(people, new Person.CompId());
System.out.println("BY ID");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(false));
System.out.println("BY Date asc");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(true));
System.out.println("BY Date desc");
for (Person p : people) {
System.out.println(p.toString());
}
}
}

Function & method reference
The Collections.sort method can sort a List using a Comparator you pass. That Comparator can be implemented using the Comparator.comparing method where you can pass a method reference as the necessary Function. Fortunately, the actual code is much simpler and shorter than this description.
For Java 8:
Collections.sort(list, comparing(ClassName::getName));
or
Collections.sort(list, comparing(ClassName::getName).reversed());
Another way is
Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder())));

Best easy way with JAVA 8 is for English Alphabetic sort
Class Implementation
public class NewspaperClass implements Comparable<NewspaperClass>{
public String name;
#Override
public int compareTo(NewspaperClass another) {
return name.compareTo(another.name);
}
}
Sort
Collections.sort(Your List);
If you want to sort for alphabet that contains non English characters you can use Locale... Below code use Turkish character sort...
Class Implementation
public class NewspaperClass implements Comparator<NewspaperClass> {
public String name;
public Boolean isUserNewspaper=false;
private Collator trCollator = Collator.getInstance(new Locale("tr_TR"));
#Override
public int compare(NewspaperClass lhs, NewspaperClass rhs) {
trCollator.setStrength(Collator.PRIMARY);
return trCollator.compare(lhs.name,rhs.name);
}
}
Sort
Collections.sort(your array list,new NewspaperClass());

You can Sort using java 8
yourList.sort(Comparator.comparing(Classname::getName));
or
yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue)));

From Java 8 and onward we don't have to use Collections.sort() directly. List interface has a default sort() method:
List<User> users = Arrays.asList(user1,user2,user3);
users.sort( (u1, u2) -> {
return u1.getFirstName.compareTo(u2.getFirstName());});
See http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html.

Java 8 Lambda shortens the sort.
Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));

You can use the Bean Comparator to sort on any property in your custom class.

Yes, that's possible for instance in this answer I sort by the property v of the class IndexValue
// Sorting by property v using a custom comparator.
Arrays.sort( array, new Comparator<IndexValue>(){
public int compare( IndexValue a, IndexValue b ){
return a.v - b.v;
}
});
If you notice here I'm creating a anonymous inner class ( which is the Java for closures ) and passing it directly to the sort method of the class Arrays
Your object may also implement Comparable ( that's what String and most of the core libraries in Java does ) but that would define the "natural sort order" of the class it self, and doesn't let you plug new ones.

I found most if not all of these answers rely on the underlying class (Object) to implement comparable or to have a helper comparable interface.
Not with my solution! The following code lets you compare object's field by knowing their string name. You could easily modify it not to use the name, but then you need to expose it or construct one of the Objects you want to compare against.
Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));
public class ReflectiveComparator {
public class FieldComparator implements Comparator<Object> {
private String fieldName;
public FieldComparator(String fieldName){
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable object1FieldValue = (Comparable) field.get(object1);
Comparable object2FieldValue = (Comparable) field.get(object2);
return object1FieldValue.compareTo(object2FieldValue);
}catch (Exception e){}
return 0;
}
}
public class ListComparator implements Comparator<Object> {
private String fieldName;
public ListComparator(String fieldName) {
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable o1FieldValue = (Comparable) field.get(object1);
Comparable o2FieldValue = (Comparable) field.get(object2);
if (o1FieldValue == null){ return -1;}
if (o2FieldValue == null){ return 1;}
return o1FieldValue.compareTo(o2FieldValue);
} catch (NoSuchFieldException e) {
throw new IllegalStateException("Field doesn't exist", e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Field inaccessible", e);
}
}
}
}

You can try Guava Ordering:
Function<Item, Date> getStartDate = new Function<Item, Date>() {
public Date apply(Item item) {
return item.getStartDate();
}
};
List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate).
sortedCopy(items);

Well if you using Java 8 or older version Here is the Best solution.
Collections.sort(studentList, Comparator.comparing(Student::getCgpa).reversed().thenComparing(Student:: getFname).thenComparing(Student::getId));
In this case, it will first sort with 'getCgpa' first and for the second part it will sort with getFname and getId. Which is field into the pojo class.

your customComparator class must implement java.util.Comparator in order to be used.
it must also overide compare() AND equals()
compare() must answer the question: Is object 1 less than, equal to or greater than object 2?
full docs: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html

This code snippets might be useful. If you want to sort an Object
in my case I want to sort by VolumeName:
public List<Volume> getSortedVolumes() throws SystemException {
List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
Collections.sort(volumes, new Comparator<Volume>() {
public int compare(Volume o1, Volume o2) {
Volume p1 = (Volume) o1;
Volume p2 = (Volume) o2;
return p1.getVolumeName().compareToIgnoreCase(
p2.getVolumeName());
}
});
return volumes;
}
This works. I use it in my jsp.

With this library here you can sort the list of custom objects on multiple columns. The library uses version 8.0 features. Sample is also available there. Here is a sample to do
SortKeys sortKeys = new SortKeys();
sortKeys.addField("firstName")
.addField("age", true); // This (true) will sort the age descending
// Other ways to specify a property to the sorter are
// .addField("lastName", String.class);
// .addField("dob", Date.class, true);
// Instantiate a ListSorter
ListSorter listSorter = new ListSorter();
// Pass the data to sort (listToSort) and the "by keys" to sort (sortKeys)
List sortedList = (List<Person>) listSorter.sortList(listToSort, sortKeys);

You can have a look into this presentation hold at the Java Forum in Stuttgart Germany in 2016.
Only a few slides use German language, 99% of the content is "English based" Java source code; like
someCollection.sort(
OurCustomComparator
.comparing(Person::getName)
.thenComparing(Person::getId)
);
where OurCustomComparator is using default methods (and other interesting ideas). As shown, leading to very concise code to pick some getter method for sorting; and super simple chaining (or reversing) of sort criteria.
If you are into java8, you find a lot of material there to get you started.

New since 1.8 is a List.sort() method instead of using the Collection.sort()
so you directly call mylistcontainer.sort()
Here is a code snippet which demonstrates the List.sort() feature:
List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Kiwi","green",40));
fruits.add(new Fruit("Banana","yellow",100));
fruits.add(new Fruit("Apple","mixed green,red",120));
fruits.add(new Fruit("Cherry","red",10));
// a) using an existing compareto() method
fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName()));
System.out.println("Using String.compareTo(): " + fruits);
//Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green]
// b) Using a comparable class
fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2));
System.out.println("Using a Comparable Fruit class (sort by color): " + fruits);
// Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow]
The Fruit class is:
public class Fruit implements Comparable<Fruit>
{
private String name;
private String color;
private int quantity;
public Fruit(String name,String color,int quantity)
{ this.name = name; this.color = color; this.quantity = quantity; }
public String getFruitName() { return name; }
public String getColor() { return color; }
public int getQuantity() { return quantity; }
#Override public final int compareTo(Fruit f) // sorting the color
{
return this.color.compareTo(f.color);
}
#Override public String toString()
{
return (name + " is: " + color);
}
} // end of Fruit class

I prefer this process:
public class SortUtil
{
public static <T> List<T> sort(List<T> list, String sortByProperty)
{
Collections.sort(list, new BeanComparator(sortByProperty));
return list;
}
}
List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate");
If you list of objects has a property called startDate, you call use this over and over. You can even chain them startDate.time.
This requires your object to be Comparable which means you need a compareTo, equals, and hashCode implementation.
Yes, it could be faster... But now you don't have to make a new Comparator for each type of sort. If you can save on dev time and give up on runtime, you might go with this one.

using the java-8 stream api you can sort an ArrayList by:
Comparator<Person> birthdayComparator = Comparator.comparing(Person::getBirthday);
List<Person> sortedList = list.stream().sorted(birthdayComparator).collect(toList());

Using Java 8 use can define the Comparator in one line using Comparator.comparing()
Use any of the following way:
Option 1:
listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate));
Option 2:
Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate));

Your custom class can implement the "Comparable" interface, which requires an implementation of the CompareTo method. In the CompareTo method, you can then define what it means that an object is less than or more than the other object. So in your example, it can look something like this:
public class MyCustomClass implements Comparable<MyCustomClass>{
..........
#Override
public int compareTo(MyCustomClass a) {
if(this.getStartDate().before(a.getStartDate())){
return -1;
}else if(a.getStartDate().before(this.getStartDate())){
return 1;
}else {
return 0;
}
}
A negative number indicates that this is smaller than the object being compared to. A positive number indicates that this is larger than the compared to object and a Zero means that the objects are equal.
You can then use the collections.sort(myList) to sort your list without having to feed in a comparator. This method also has the advantage of having things sorted automatically if you use a sorted collection data structures like a TreeSet or a TreeMap.
You can check this article if you would like to read more about the Comparable interface (disclosure: I am the author ;) )
https://nullbeans.com/the-java-comparable-interface-automatic-sort-of-collections/

You could also use Springs PropertyComparator if you have just a String property path to the (nested) property you want to sort:
List<SomeObject> list = ...;
PropertyComparator<HitWithInfo> propertyComparator = new PropertyComparator<>(
"property.nested.myProperty", false, true);
list.sort(propertyComparator);
The drawback is, that this comparator silently ignores properties which does not exist or are not accessible and handles this as null value for comparison. This means, you should carefully test such a comparator or validate the existence of the property path somehow.

I have tried lots of different solutions available on internet but solution which works for me is available at below link.
https://www.java67.com/2017/07/how-to-sort-arraylist-of-objects-using.html

Related

How can I implement a method which will help me to sort a list using Comparator in Java? [duplicate]

I read about sorting ArrayLists using a Comparator but in all of the examples people used compareTo which according to some research is a method for Strings.
I wanted to sort an ArrayList of custom objects by one of their properties: a Date object
(getStartDay()). Normally I compare them by item1.getStartDate().before(item2.getStartDate()) so I was wondering whether I could write something like:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...
}
Since Date implements Comparable, it has a compareTo method just like String does.
So your custom Comparator could look like this:
public class CustomComparator implements Comparator<MyObject> {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
The compare() method must return an int, so you couldn't directly return a boolean like you were planning to anyway.
Your sorting code would be just about like you wrote:
Collections.sort(Database.arrayList, new CustomComparator());
A slightly shorter way to write all this, if you don't need to reuse your comparator, is to write it as an inline anonymous class:
Collections.sort(Database.arrayList, new Comparator<MyObject>() {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
Since java-8
You can now write the last example in a shorter form by using a lambda expression for the Comparator:
Collections.sort(Database.arrayList,
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
And List has a sort(Comparator) method, so you can shorten this even further:
Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
This is such a common idiom that there's a built-in method to generate a Comparator for a class with a Comparable key:
Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));
All of these are equivalent forms.
Classes that has a natural sort order (a class Number, as an example) should implement the Comparable interface, whilst classes that has no natural sort order (a class Chair, as an example) should be provided with a Comparator (or an anonymous Comparator class).
Two examples:
public class Number implements Comparable<Number> {
private int value;
public Number(int value) { this.value = value; }
public int compareTo(Number anotherInstance) {
return this.value - anotherInstance.value;
}
}
public class Chair {
private int weight;
private int height;
public Chair(int weight, int height) {
this.weight = weight;
this.height = height;
}
/* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getWeight() - chair2.getWeight();
}
}
class ChairHeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getHeight() - chair2.getHeight();
}
}
Usage:
List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);
List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());
// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
public int compare(Chair chair1, Chair chair2) {
...
}
});
For sorting an ArrayList you could use the following code snippet:
Collections.sort(studList, new Comparator<Student>(){
public int compare(Student s1, Student s2) {
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
}
});
JAVA 8 lambda expression
Collections.sort(studList, (Student s1, Student s2) ->{
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});
OR
Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)
Yes, you can. There are two options with comparing items, the Comparable interface, and the Comparator interface.
Both of these interfaces allow for different behavior. Comparable allows you to make the object act like you just described Strings (in fact, String implements Comparable). The second, Comparator, allows you to do what you are asking to do. You would do it like this:
Collections.sort(myArrayList, new MyComparator());
That will cause the Collections.sort method to use your comparator for it's sorting mechanism. If the objects in the ArrayList implement comparable, you can instead do something like this:
Collections.sort(myArrayList);
The Collections class contains a number of these useful, common tools.
With Java 8 you can use a method reference for your comparator:
import static java.util.Comparator.comparing;
Collections.sort(list, comparing(MyObject::getStartDate));
Since technologies appear everyday, the answer will change in the time. I took a look at LambdaJ and seems very interesting.
You can try solving these tasks with LambdaJ. You can find it here: http://code.google.com/p/lambdaj/
Here you have an example:
Sort Iterative
List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
}
});
Sort with lambda
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
Of course, having this kind of beauty impacts in the performance (an average of 2 times), but can you find a more readable code?
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
public class test {
public static class Person {
public String name;
public int id;
public Date hireDate;
public Person(String iname, int iid, Date ihireDate) {
name = iname;
id = iid;
hireDate = ihireDate;
}
public String toString() {
return name + " " + id + " " + hireDate.toString();
}
// Comparator
public static class CompId implements Comparator<Person> {
#Override
public int compare(Person arg0, Person arg1) {
return arg0.id - arg1.id;
}
}
public static class CompDate implements Comparator<Person> {
private int mod = 1;
public CompDate(boolean desc) {
if (desc) mod =-1;
}
#Override
public int compare(Person arg0, Person arg1) {
return mod*arg0.hireDate.compareTo(arg1.hireDate);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
ArrayList<Person> people;
people = new ArrayList<Person>();
try {
people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Collections.sort(people, new Person.CompId());
System.out.println("BY ID");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(false));
System.out.println("BY Date asc");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(true));
System.out.println("BY Date desc");
for (Person p : people) {
System.out.println(p.toString());
}
}
}
Function & method reference
The Collections.sort method can sort a List using a Comparator you pass. That Comparator can be implemented using the Comparator.comparing method where you can pass a method reference as the necessary Function. Fortunately, the actual code is much simpler and shorter than this description.
For Java 8:
Collections.sort(list, comparing(ClassName::getName));
or
Collections.sort(list, comparing(ClassName::getName).reversed());
Another way is
Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder())));
Best easy way with JAVA 8 is for English Alphabetic sort
Class Implementation
public class NewspaperClass implements Comparable<NewspaperClass>{
public String name;
#Override
public int compareTo(NewspaperClass another) {
return name.compareTo(another.name);
}
}
Sort
Collections.sort(Your List);
If you want to sort for alphabet that contains non English characters you can use Locale... Below code use Turkish character sort...
Class Implementation
public class NewspaperClass implements Comparator<NewspaperClass> {
public String name;
public Boolean isUserNewspaper=false;
private Collator trCollator = Collator.getInstance(new Locale("tr_TR"));
#Override
public int compare(NewspaperClass lhs, NewspaperClass rhs) {
trCollator.setStrength(Collator.PRIMARY);
return trCollator.compare(lhs.name,rhs.name);
}
}
Sort
Collections.sort(your array list,new NewspaperClass());
You can Sort using java 8
yourList.sort(Comparator.comparing(Classname::getName));
or
yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue)));
From Java 8 and onward we don't have to use Collections.sort() directly. List interface has a default sort() method:
List<User> users = Arrays.asList(user1,user2,user3);
users.sort( (u1, u2) -> {
return u1.getFirstName.compareTo(u2.getFirstName());});
See http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html.
Java 8 Lambda shortens the sort.
Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));
You can use the Bean Comparator to sort on any property in your custom class.
Yes, that's possible for instance in this answer I sort by the property v of the class IndexValue
// Sorting by property v using a custom comparator.
Arrays.sort( array, new Comparator<IndexValue>(){
public int compare( IndexValue a, IndexValue b ){
return a.v - b.v;
}
});
If you notice here I'm creating a anonymous inner class ( which is the Java for closures ) and passing it directly to the sort method of the class Arrays
Your object may also implement Comparable ( that's what String and most of the core libraries in Java does ) but that would define the "natural sort order" of the class it self, and doesn't let you plug new ones.
I found most if not all of these answers rely on the underlying class (Object) to implement comparable or to have a helper comparable interface.
Not with my solution! The following code lets you compare object's field by knowing their string name. You could easily modify it not to use the name, but then you need to expose it or construct one of the Objects you want to compare against.
Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));
public class ReflectiveComparator {
public class FieldComparator implements Comparator<Object> {
private String fieldName;
public FieldComparator(String fieldName){
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable object1FieldValue = (Comparable) field.get(object1);
Comparable object2FieldValue = (Comparable) field.get(object2);
return object1FieldValue.compareTo(object2FieldValue);
}catch (Exception e){}
return 0;
}
}
public class ListComparator implements Comparator<Object> {
private String fieldName;
public ListComparator(String fieldName) {
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable o1FieldValue = (Comparable) field.get(object1);
Comparable o2FieldValue = (Comparable) field.get(object2);
if (o1FieldValue == null){ return -1;}
if (o2FieldValue == null){ return 1;}
return o1FieldValue.compareTo(o2FieldValue);
} catch (NoSuchFieldException e) {
throw new IllegalStateException("Field doesn't exist", e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Field inaccessible", e);
}
}
}
}
You can try Guava Ordering:
Function<Item, Date> getStartDate = new Function<Item, Date>() {
public Date apply(Item item) {
return item.getStartDate();
}
};
List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate).
sortedCopy(items);
Well if you using Java 8 or older version Here is the Best solution.
Collections.sort(studentList, Comparator.comparing(Student::getCgpa).reversed().thenComparing(Student:: getFname).thenComparing(Student::getId));
In this case, it will first sort with 'getCgpa' first and for the second part it will sort with getFname and getId. Which is field into the pojo class.
your customComparator class must implement java.util.Comparator in order to be used.
it must also overide compare() AND equals()
compare() must answer the question: Is object 1 less than, equal to or greater than object 2?
full docs: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html
This code snippets might be useful. If you want to sort an Object
in my case I want to sort by VolumeName:
public List<Volume> getSortedVolumes() throws SystemException {
List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
Collections.sort(volumes, new Comparator<Volume>() {
public int compare(Volume o1, Volume o2) {
Volume p1 = (Volume) o1;
Volume p2 = (Volume) o2;
return p1.getVolumeName().compareToIgnoreCase(
p2.getVolumeName());
}
});
return volumes;
}
This works. I use it in my jsp.
With this library here you can sort the list of custom objects on multiple columns. The library uses version 8.0 features. Sample is also available there. Here is a sample to do
SortKeys sortKeys = new SortKeys();
sortKeys.addField("firstName")
.addField("age", true); // This (true) will sort the age descending
// Other ways to specify a property to the sorter are
// .addField("lastName", String.class);
// .addField("dob", Date.class, true);
// Instantiate a ListSorter
ListSorter listSorter = new ListSorter();
// Pass the data to sort (listToSort) and the "by keys" to sort (sortKeys)
List sortedList = (List<Person>) listSorter.sortList(listToSort, sortKeys);
You can have a look into this presentation hold at the Java Forum in Stuttgart Germany in 2016.
Only a few slides use German language, 99% of the content is "English based" Java source code; like
someCollection.sort(
OurCustomComparator
.comparing(Person::getName)
.thenComparing(Person::getId)
);
where OurCustomComparator is using default methods (and other interesting ideas). As shown, leading to very concise code to pick some getter method for sorting; and super simple chaining (or reversing) of sort criteria.
If you are into java8, you find a lot of material there to get you started.
New since 1.8 is a List.sort() method instead of using the Collection.sort()
so you directly call mylistcontainer.sort()
Here is a code snippet which demonstrates the List.sort() feature:
List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Kiwi","green",40));
fruits.add(new Fruit("Banana","yellow",100));
fruits.add(new Fruit("Apple","mixed green,red",120));
fruits.add(new Fruit("Cherry","red",10));
// a) using an existing compareto() method
fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName()));
System.out.println("Using String.compareTo(): " + fruits);
//Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green]
// b) Using a comparable class
fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2));
System.out.println("Using a Comparable Fruit class (sort by color): " + fruits);
// Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow]
The Fruit class is:
public class Fruit implements Comparable<Fruit>
{
private String name;
private String color;
private int quantity;
public Fruit(String name,String color,int quantity)
{ this.name = name; this.color = color; this.quantity = quantity; }
public String getFruitName() { return name; }
public String getColor() { return color; }
public int getQuantity() { return quantity; }
#Override public final int compareTo(Fruit f) // sorting the color
{
return this.color.compareTo(f.color);
}
#Override public String toString()
{
return (name + " is: " + color);
}
} // end of Fruit class
I prefer this process:
public class SortUtil
{
public static <T> List<T> sort(List<T> list, String sortByProperty)
{
Collections.sort(list, new BeanComparator(sortByProperty));
return list;
}
}
List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate");
If you list of objects has a property called startDate, you call use this over and over. You can even chain them startDate.time.
This requires your object to be Comparable which means you need a compareTo, equals, and hashCode implementation.
Yes, it could be faster... But now you don't have to make a new Comparator for each type of sort. If you can save on dev time and give up on runtime, you might go with this one.
using the java-8 stream api you can sort an ArrayList by:
Comparator<Person> birthdayComparator = Comparator.comparing(Person::getBirthday);
List<Person> sortedList = list.stream().sorted(birthdayComparator).collect(toList());
Using Java 8 use can define the Comparator in one line using Comparator.comparing()
Use any of the following way:
Option 1:
listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate));
Option 2:
Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate));
Your custom class can implement the "Comparable" interface, which requires an implementation of the CompareTo method. In the CompareTo method, you can then define what it means that an object is less than or more than the other object. So in your example, it can look something like this:
public class MyCustomClass implements Comparable<MyCustomClass>{
..........
#Override
public int compareTo(MyCustomClass a) {
if(this.getStartDate().before(a.getStartDate())){
return -1;
}else if(a.getStartDate().before(this.getStartDate())){
return 1;
}else {
return 0;
}
}
A negative number indicates that this is smaller than the object being compared to. A positive number indicates that this is larger than the compared to object and a Zero means that the objects are equal.
You can then use the collections.sort(myList) to sort your list without having to feed in a comparator. This method also has the advantage of having things sorted automatically if you use a sorted collection data structures like a TreeSet or a TreeMap.
You can check this article if you would like to read more about the Comparable interface (disclosure: I am the author ;) )
https://nullbeans.com/the-java-comparable-interface-automatic-sort-of-collections/
You could also use Springs PropertyComparator if you have just a String property path to the (nested) property you want to sort:
List<SomeObject> list = ...;
PropertyComparator<HitWithInfo> propertyComparator = new PropertyComparator<>(
"property.nested.myProperty", false, true);
list.sort(propertyComparator);
The drawback is, that this comparator silently ignores properties which does not exist or are not accessible and handles this as null value for comparison. This means, you should carefully test such a comparator or validate the existence of the property path somehow.
I have tried lots of different solutions available on internet but solution which works for me is available at below link.
https://www.java67.com/2017/07/how-to-sort-arraylist-of-objects-using.html

How to sort an ArrayList of objects based on multiple variation [duplicate]

I read about sorting ArrayLists using a Comparator but in all of the examples people used compareTo which according to some research is a method for Strings.
I wanted to sort an ArrayList of custom objects by one of their properties: a Date object
(getStartDay()). Normally I compare them by item1.getStartDate().before(item2.getStartDate()) so I was wondering whether I could write something like:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...
}
Since Date implements Comparable, it has a compareTo method just like String does.
So your custom Comparator could look like this:
public class CustomComparator implements Comparator<MyObject> {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
The compare() method must return an int, so you couldn't directly return a boolean like you were planning to anyway.
Your sorting code would be just about like you wrote:
Collections.sort(Database.arrayList, new CustomComparator());
A slightly shorter way to write all this, if you don't need to reuse your comparator, is to write it as an inline anonymous class:
Collections.sort(Database.arrayList, new Comparator<MyObject>() {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
Since java-8
You can now write the last example in a shorter form by using a lambda expression for the Comparator:
Collections.sort(Database.arrayList,
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
And List has a sort(Comparator) method, so you can shorten this even further:
Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
This is such a common idiom that there's a built-in method to generate a Comparator for a class with a Comparable key:
Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));
All of these are equivalent forms.
Classes that has a natural sort order (a class Number, as an example) should implement the Comparable interface, whilst classes that has no natural sort order (a class Chair, as an example) should be provided with a Comparator (or an anonymous Comparator class).
Two examples:
public class Number implements Comparable<Number> {
private int value;
public Number(int value) { this.value = value; }
public int compareTo(Number anotherInstance) {
return this.value - anotherInstance.value;
}
}
public class Chair {
private int weight;
private int height;
public Chair(int weight, int height) {
this.weight = weight;
this.height = height;
}
/* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getWeight() - chair2.getWeight();
}
}
class ChairHeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getHeight() - chair2.getHeight();
}
}
Usage:
List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);
List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());
// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
public int compare(Chair chair1, Chair chair2) {
...
}
});
For sorting an ArrayList you could use the following code snippet:
Collections.sort(studList, new Comparator<Student>(){
public int compare(Student s1, Student s2) {
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
}
});
JAVA 8 lambda expression
Collections.sort(studList, (Student s1, Student s2) ->{
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});
OR
Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)
Yes, you can. There are two options with comparing items, the Comparable interface, and the Comparator interface.
Both of these interfaces allow for different behavior. Comparable allows you to make the object act like you just described Strings (in fact, String implements Comparable). The second, Comparator, allows you to do what you are asking to do. You would do it like this:
Collections.sort(myArrayList, new MyComparator());
That will cause the Collections.sort method to use your comparator for it's sorting mechanism. If the objects in the ArrayList implement comparable, you can instead do something like this:
Collections.sort(myArrayList);
The Collections class contains a number of these useful, common tools.
With Java 8 you can use a method reference for your comparator:
import static java.util.Comparator.comparing;
Collections.sort(list, comparing(MyObject::getStartDate));
Since technologies appear everyday, the answer will change in the time. I took a look at LambdaJ and seems very interesting.
You can try solving these tasks with LambdaJ. You can find it here: http://code.google.com/p/lambdaj/
Here you have an example:
Sort Iterative
List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
}
});
Sort with lambda
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
Of course, having this kind of beauty impacts in the performance (an average of 2 times), but can you find a more readable code?
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
public class test {
public static class Person {
public String name;
public int id;
public Date hireDate;
public Person(String iname, int iid, Date ihireDate) {
name = iname;
id = iid;
hireDate = ihireDate;
}
public String toString() {
return name + " " + id + " " + hireDate.toString();
}
// Comparator
public static class CompId implements Comparator<Person> {
#Override
public int compare(Person arg0, Person arg1) {
return arg0.id - arg1.id;
}
}
public static class CompDate implements Comparator<Person> {
private int mod = 1;
public CompDate(boolean desc) {
if (desc) mod =-1;
}
#Override
public int compare(Person arg0, Person arg1) {
return mod*arg0.hireDate.compareTo(arg1.hireDate);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
ArrayList<Person> people;
people = new ArrayList<Person>();
try {
people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Collections.sort(people, new Person.CompId());
System.out.println("BY ID");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(false));
System.out.println("BY Date asc");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(true));
System.out.println("BY Date desc");
for (Person p : people) {
System.out.println(p.toString());
}
}
}
Function & method reference
The Collections.sort method can sort a List using a Comparator you pass. That Comparator can be implemented using the Comparator.comparing method where you can pass a method reference as the necessary Function. Fortunately, the actual code is much simpler and shorter than this description.
For Java 8:
Collections.sort(list, comparing(ClassName::getName));
or
Collections.sort(list, comparing(ClassName::getName).reversed());
Another way is
Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder())));
Best easy way with JAVA 8 is for English Alphabetic sort
Class Implementation
public class NewspaperClass implements Comparable<NewspaperClass>{
public String name;
#Override
public int compareTo(NewspaperClass another) {
return name.compareTo(another.name);
}
}
Sort
Collections.sort(Your List);
If you want to sort for alphabet that contains non English characters you can use Locale... Below code use Turkish character sort...
Class Implementation
public class NewspaperClass implements Comparator<NewspaperClass> {
public String name;
public Boolean isUserNewspaper=false;
private Collator trCollator = Collator.getInstance(new Locale("tr_TR"));
#Override
public int compare(NewspaperClass lhs, NewspaperClass rhs) {
trCollator.setStrength(Collator.PRIMARY);
return trCollator.compare(lhs.name,rhs.name);
}
}
Sort
Collections.sort(your array list,new NewspaperClass());
You can Sort using java 8
yourList.sort(Comparator.comparing(Classname::getName));
or
yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue)));
From Java 8 and onward we don't have to use Collections.sort() directly. List interface has a default sort() method:
List<User> users = Arrays.asList(user1,user2,user3);
users.sort( (u1, u2) -> {
return u1.getFirstName.compareTo(u2.getFirstName());});
See http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html.
Java 8 Lambda shortens the sort.
Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));
You can use the Bean Comparator to sort on any property in your custom class.
Yes, that's possible for instance in this answer I sort by the property v of the class IndexValue
// Sorting by property v using a custom comparator.
Arrays.sort( array, new Comparator<IndexValue>(){
public int compare( IndexValue a, IndexValue b ){
return a.v - b.v;
}
});
If you notice here I'm creating a anonymous inner class ( which is the Java for closures ) and passing it directly to the sort method of the class Arrays
Your object may also implement Comparable ( that's what String and most of the core libraries in Java does ) but that would define the "natural sort order" of the class it self, and doesn't let you plug new ones.
I found most if not all of these answers rely on the underlying class (Object) to implement comparable or to have a helper comparable interface.
Not with my solution! The following code lets you compare object's field by knowing their string name. You could easily modify it not to use the name, but then you need to expose it or construct one of the Objects you want to compare against.
Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));
public class ReflectiveComparator {
public class FieldComparator implements Comparator<Object> {
private String fieldName;
public FieldComparator(String fieldName){
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable object1FieldValue = (Comparable) field.get(object1);
Comparable object2FieldValue = (Comparable) field.get(object2);
return object1FieldValue.compareTo(object2FieldValue);
}catch (Exception e){}
return 0;
}
}
public class ListComparator implements Comparator<Object> {
private String fieldName;
public ListComparator(String fieldName) {
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable o1FieldValue = (Comparable) field.get(object1);
Comparable o2FieldValue = (Comparable) field.get(object2);
if (o1FieldValue == null){ return -1;}
if (o2FieldValue == null){ return 1;}
return o1FieldValue.compareTo(o2FieldValue);
} catch (NoSuchFieldException e) {
throw new IllegalStateException("Field doesn't exist", e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Field inaccessible", e);
}
}
}
}
You can try Guava Ordering:
Function<Item, Date> getStartDate = new Function<Item, Date>() {
public Date apply(Item item) {
return item.getStartDate();
}
};
List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate).
sortedCopy(items);
Well if you using Java 8 or older version Here is the Best solution.
Collections.sort(studentList, Comparator.comparing(Student::getCgpa).reversed().thenComparing(Student:: getFname).thenComparing(Student::getId));
In this case, it will first sort with 'getCgpa' first and for the second part it will sort with getFname and getId. Which is field into the pojo class.
your customComparator class must implement java.util.Comparator in order to be used.
it must also overide compare() AND equals()
compare() must answer the question: Is object 1 less than, equal to or greater than object 2?
full docs: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html
This code snippets might be useful. If you want to sort an Object
in my case I want to sort by VolumeName:
public List<Volume> getSortedVolumes() throws SystemException {
List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
Collections.sort(volumes, new Comparator<Volume>() {
public int compare(Volume o1, Volume o2) {
Volume p1 = (Volume) o1;
Volume p2 = (Volume) o2;
return p1.getVolumeName().compareToIgnoreCase(
p2.getVolumeName());
}
});
return volumes;
}
This works. I use it in my jsp.
With this library here you can sort the list of custom objects on multiple columns. The library uses version 8.0 features. Sample is also available there. Here is a sample to do
SortKeys sortKeys = new SortKeys();
sortKeys.addField("firstName")
.addField("age", true); // This (true) will sort the age descending
// Other ways to specify a property to the sorter are
// .addField("lastName", String.class);
// .addField("dob", Date.class, true);
// Instantiate a ListSorter
ListSorter listSorter = new ListSorter();
// Pass the data to sort (listToSort) and the "by keys" to sort (sortKeys)
List sortedList = (List<Person>) listSorter.sortList(listToSort, sortKeys);
You can have a look into this presentation hold at the Java Forum in Stuttgart Germany in 2016.
Only a few slides use German language, 99% of the content is "English based" Java source code; like
someCollection.sort(
OurCustomComparator
.comparing(Person::getName)
.thenComparing(Person::getId)
);
where OurCustomComparator is using default methods (and other interesting ideas). As shown, leading to very concise code to pick some getter method for sorting; and super simple chaining (or reversing) of sort criteria.
If you are into java8, you find a lot of material there to get you started.
New since 1.8 is a List.sort() method instead of using the Collection.sort()
so you directly call mylistcontainer.sort()
Here is a code snippet which demonstrates the List.sort() feature:
List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Kiwi","green",40));
fruits.add(new Fruit("Banana","yellow",100));
fruits.add(new Fruit("Apple","mixed green,red",120));
fruits.add(new Fruit("Cherry","red",10));
// a) using an existing compareto() method
fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName()));
System.out.println("Using String.compareTo(): " + fruits);
//Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green]
// b) Using a comparable class
fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2));
System.out.println("Using a Comparable Fruit class (sort by color): " + fruits);
// Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow]
The Fruit class is:
public class Fruit implements Comparable<Fruit>
{
private String name;
private String color;
private int quantity;
public Fruit(String name,String color,int quantity)
{ this.name = name; this.color = color; this.quantity = quantity; }
public String getFruitName() { return name; }
public String getColor() { return color; }
public int getQuantity() { return quantity; }
#Override public final int compareTo(Fruit f) // sorting the color
{
return this.color.compareTo(f.color);
}
#Override public String toString()
{
return (name + " is: " + color);
}
} // end of Fruit class
I prefer this process:
public class SortUtil
{
public static <T> List<T> sort(List<T> list, String sortByProperty)
{
Collections.sort(list, new BeanComparator(sortByProperty));
return list;
}
}
List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate");
If you list of objects has a property called startDate, you call use this over and over. You can even chain them startDate.time.
This requires your object to be Comparable which means you need a compareTo, equals, and hashCode implementation.
Yes, it could be faster... But now you don't have to make a new Comparator for each type of sort. If you can save on dev time and give up on runtime, you might go with this one.
using the java-8 stream api you can sort an ArrayList by:
Comparator<Person> birthdayComparator = Comparator.comparing(Person::getBirthday);
List<Person> sortedList = list.stream().sorted(birthdayComparator).collect(toList());
Using Java 8 use can define the Comparator in one line using Comparator.comparing()
Use any of the following way:
Option 1:
listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate));
Option 2:
Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate));
Your custom class can implement the "Comparable" interface, which requires an implementation of the CompareTo method. In the CompareTo method, you can then define what it means that an object is less than or more than the other object. So in your example, it can look something like this:
public class MyCustomClass implements Comparable<MyCustomClass>{
..........
#Override
public int compareTo(MyCustomClass a) {
if(this.getStartDate().before(a.getStartDate())){
return -1;
}else if(a.getStartDate().before(this.getStartDate())){
return 1;
}else {
return 0;
}
}
A negative number indicates that this is smaller than the object being compared to. A positive number indicates that this is larger than the compared to object and a Zero means that the objects are equal.
You can then use the collections.sort(myList) to sort your list without having to feed in a comparator. This method also has the advantage of having things sorted automatically if you use a sorted collection data structures like a TreeSet or a TreeMap.
You can check this article if you would like to read more about the Comparable interface (disclosure: I am the author ;) )
https://nullbeans.com/the-java-comparable-interface-automatic-sort-of-collections/
You could also use Springs PropertyComparator if you have just a String property path to the (nested) property you want to sort:
List<SomeObject> list = ...;
PropertyComparator<HitWithInfo> propertyComparator = new PropertyComparator<>(
"property.nested.myProperty", false, true);
list.sort(propertyComparator);
The drawback is, that this comparator silently ignores properties which does not exist or are not accessible and handles this as null value for comparison. This means, you should carefully test such a comparator or validate the existence of the property path somehow.
I have tried lots of different solutions available on internet but solution which works for me is available at below link.
https://www.java67.com/2017/07/how-to-sort-arraylist-of-objects-using.html

How to output the content of this list in certain order? [duplicate]

I read about sorting ArrayLists using a Comparator but in all of the examples people used compareTo which according to some research is a method for Strings.
I wanted to sort an ArrayList of custom objects by one of their properties: a Date object
(getStartDay()). Normally I compare them by item1.getStartDate().before(item2.getStartDate()) so I was wondering whether I could write something like:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...
}
Since Date implements Comparable, it has a compareTo method just like String does.
So your custom Comparator could look like this:
public class CustomComparator implements Comparator<MyObject> {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
The compare() method must return an int, so you couldn't directly return a boolean like you were planning to anyway.
Your sorting code would be just about like you wrote:
Collections.sort(Database.arrayList, new CustomComparator());
A slightly shorter way to write all this, if you don't need to reuse your comparator, is to write it as an inline anonymous class:
Collections.sort(Database.arrayList, new Comparator<MyObject>() {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
Since java-8
You can now write the last example in a shorter form by using a lambda expression for the Comparator:
Collections.sort(Database.arrayList,
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
And List has a sort(Comparator) method, so you can shorten this even further:
Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
This is such a common idiom that there's a built-in method to generate a Comparator for a class with a Comparable key:
Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));
All of these are equivalent forms.
Classes that has a natural sort order (a class Number, as an example) should implement the Comparable interface, whilst classes that has no natural sort order (a class Chair, as an example) should be provided with a Comparator (or an anonymous Comparator class).
Two examples:
public class Number implements Comparable<Number> {
private int value;
public Number(int value) { this.value = value; }
public int compareTo(Number anotherInstance) {
return this.value - anotherInstance.value;
}
}
public class Chair {
private int weight;
private int height;
public Chair(int weight, int height) {
this.weight = weight;
this.height = height;
}
/* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getWeight() - chair2.getWeight();
}
}
class ChairHeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getHeight() - chair2.getHeight();
}
}
Usage:
List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);
List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());
// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
public int compare(Chair chair1, Chair chair2) {
...
}
});
For sorting an ArrayList you could use the following code snippet:
Collections.sort(studList, new Comparator<Student>(){
public int compare(Student s1, Student s2) {
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
}
});
JAVA 8 lambda expression
Collections.sort(studList, (Student s1, Student s2) ->{
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});
OR
Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)
Yes, you can. There are two options with comparing items, the Comparable interface, and the Comparator interface.
Both of these interfaces allow for different behavior. Comparable allows you to make the object act like you just described Strings (in fact, String implements Comparable). The second, Comparator, allows you to do what you are asking to do. You would do it like this:
Collections.sort(myArrayList, new MyComparator());
That will cause the Collections.sort method to use your comparator for it's sorting mechanism. If the objects in the ArrayList implement comparable, you can instead do something like this:
Collections.sort(myArrayList);
The Collections class contains a number of these useful, common tools.
With Java 8 you can use a method reference for your comparator:
import static java.util.Comparator.comparing;
Collections.sort(list, comparing(MyObject::getStartDate));
Since technologies appear everyday, the answer will change in the time. I took a look at LambdaJ and seems very interesting.
You can try solving these tasks with LambdaJ. You can find it here: http://code.google.com/p/lambdaj/
Here you have an example:
Sort Iterative
List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
}
});
Sort with lambda
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
Of course, having this kind of beauty impacts in the performance (an average of 2 times), but can you find a more readable code?
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
public class test {
public static class Person {
public String name;
public int id;
public Date hireDate;
public Person(String iname, int iid, Date ihireDate) {
name = iname;
id = iid;
hireDate = ihireDate;
}
public String toString() {
return name + " " + id + " " + hireDate.toString();
}
// Comparator
public static class CompId implements Comparator<Person> {
#Override
public int compare(Person arg0, Person arg1) {
return arg0.id - arg1.id;
}
}
public static class CompDate implements Comparator<Person> {
private int mod = 1;
public CompDate(boolean desc) {
if (desc) mod =-1;
}
#Override
public int compare(Person arg0, Person arg1) {
return mod*arg0.hireDate.compareTo(arg1.hireDate);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
ArrayList<Person> people;
people = new ArrayList<Person>();
try {
people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Collections.sort(people, new Person.CompId());
System.out.println("BY ID");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(false));
System.out.println("BY Date asc");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(true));
System.out.println("BY Date desc");
for (Person p : people) {
System.out.println(p.toString());
}
}
}
Function & method reference
The Collections.sort method can sort a List using a Comparator you pass. That Comparator can be implemented using the Comparator.comparing method where you can pass a method reference as the necessary Function. Fortunately, the actual code is much simpler and shorter than this description.
For Java 8:
Collections.sort(list, comparing(ClassName::getName));
or
Collections.sort(list, comparing(ClassName::getName).reversed());
Another way is
Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder())));
Best easy way with JAVA 8 is for English Alphabetic sort
Class Implementation
public class NewspaperClass implements Comparable<NewspaperClass>{
public String name;
#Override
public int compareTo(NewspaperClass another) {
return name.compareTo(another.name);
}
}
Sort
Collections.sort(Your List);
If you want to sort for alphabet that contains non English characters you can use Locale... Below code use Turkish character sort...
Class Implementation
public class NewspaperClass implements Comparator<NewspaperClass> {
public String name;
public Boolean isUserNewspaper=false;
private Collator trCollator = Collator.getInstance(new Locale("tr_TR"));
#Override
public int compare(NewspaperClass lhs, NewspaperClass rhs) {
trCollator.setStrength(Collator.PRIMARY);
return trCollator.compare(lhs.name,rhs.name);
}
}
Sort
Collections.sort(your array list,new NewspaperClass());
You can Sort using java 8
yourList.sort(Comparator.comparing(Classname::getName));
or
yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue)));
From Java 8 and onward we don't have to use Collections.sort() directly. List interface has a default sort() method:
List<User> users = Arrays.asList(user1,user2,user3);
users.sort( (u1, u2) -> {
return u1.getFirstName.compareTo(u2.getFirstName());});
See http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html.
Java 8 Lambda shortens the sort.
Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));
You can use the Bean Comparator to sort on any property in your custom class.
Yes, that's possible for instance in this answer I sort by the property v of the class IndexValue
// Sorting by property v using a custom comparator.
Arrays.sort( array, new Comparator<IndexValue>(){
public int compare( IndexValue a, IndexValue b ){
return a.v - b.v;
}
});
If you notice here I'm creating a anonymous inner class ( which is the Java for closures ) and passing it directly to the sort method of the class Arrays
Your object may also implement Comparable ( that's what String and most of the core libraries in Java does ) but that would define the "natural sort order" of the class it self, and doesn't let you plug new ones.
I found most if not all of these answers rely on the underlying class (Object) to implement comparable or to have a helper comparable interface.
Not with my solution! The following code lets you compare object's field by knowing their string name. You could easily modify it not to use the name, but then you need to expose it or construct one of the Objects you want to compare against.
Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));
public class ReflectiveComparator {
public class FieldComparator implements Comparator<Object> {
private String fieldName;
public FieldComparator(String fieldName){
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable object1FieldValue = (Comparable) field.get(object1);
Comparable object2FieldValue = (Comparable) field.get(object2);
return object1FieldValue.compareTo(object2FieldValue);
}catch (Exception e){}
return 0;
}
}
public class ListComparator implements Comparator<Object> {
private String fieldName;
public ListComparator(String fieldName) {
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable o1FieldValue = (Comparable) field.get(object1);
Comparable o2FieldValue = (Comparable) field.get(object2);
if (o1FieldValue == null){ return -1;}
if (o2FieldValue == null){ return 1;}
return o1FieldValue.compareTo(o2FieldValue);
} catch (NoSuchFieldException e) {
throw new IllegalStateException("Field doesn't exist", e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Field inaccessible", e);
}
}
}
}
You can try Guava Ordering:
Function<Item, Date> getStartDate = new Function<Item, Date>() {
public Date apply(Item item) {
return item.getStartDate();
}
};
List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate).
sortedCopy(items);
Well if you using Java 8 or older version Here is the Best solution.
Collections.sort(studentList, Comparator.comparing(Student::getCgpa).reversed().thenComparing(Student:: getFname).thenComparing(Student::getId));
In this case, it will first sort with 'getCgpa' first and for the second part it will sort with getFname and getId. Which is field into the pojo class.
your customComparator class must implement java.util.Comparator in order to be used.
it must also overide compare() AND equals()
compare() must answer the question: Is object 1 less than, equal to or greater than object 2?
full docs: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html
This code snippets might be useful. If you want to sort an Object
in my case I want to sort by VolumeName:
public List<Volume> getSortedVolumes() throws SystemException {
List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
Collections.sort(volumes, new Comparator<Volume>() {
public int compare(Volume o1, Volume o2) {
Volume p1 = (Volume) o1;
Volume p2 = (Volume) o2;
return p1.getVolumeName().compareToIgnoreCase(
p2.getVolumeName());
}
});
return volumes;
}
This works. I use it in my jsp.
With this library here you can sort the list of custom objects on multiple columns. The library uses version 8.0 features. Sample is also available there. Here is a sample to do
SortKeys sortKeys = new SortKeys();
sortKeys.addField("firstName")
.addField("age", true); // This (true) will sort the age descending
// Other ways to specify a property to the sorter are
// .addField("lastName", String.class);
// .addField("dob", Date.class, true);
// Instantiate a ListSorter
ListSorter listSorter = new ListSorter();
// Pass the data to sort (listToSort) and the "by keys" to sort (sortKeys)
List sortedList = (List<Person>) listSorter.sortList(listToSort, sortKeys);
You can have a look into this presentation hold at the Java Forum in Stuttgart Germany in 2016.
Only a few slides use German language, 99% of the content is "English based" Java source code; like
someCollection.sort(
OurCustomComparator
.comparing(Person::getName)
.thenComparing(Person::getId)
);
where OurCustomComparator is using default methods (and other interesting ideas). As shown, leading to very concise code to pick some getter method for sorting; and super simple chaining (or reversing) of sort criteria.
If you are into java8, you find a lot of material there to get you started.
New since 1.8 is a List.sort() method instead of using the Collection.sort()
so you directly call mylistcontainer.sort()
Here is a code snippet which demonstrates the List.sort() feature:
List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Kiwi","green",40));
fruits.add(new Fruit("Banana","yellow",100));
fruits.add(new Fruit("Apple","mixed green,red",120));
fruits.add(new Fruit("Cherry","red",10));
// a) using an existing compareto() method
fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName()));
System.out.println("Using String.compareTo(): " + fruits);
//Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green]
// b) Using a comparable class
fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2));
System.out.println("Using a Comparable Fruit class (sort by color): " + fruits);
// Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow]
The Fruit class is:
public class Fruit implements Comparable<Fruit>
{
private String name;
private String color;
private int quantity;
public Fruit(String name,String color,int quantity)
{ this.name = name; this.color = color; this.quantity = quantity; }
public String getFruitName() { return name; }
public String getColor() { return color; }
public int getQuantity() { return quantity; }
#Override public final int compareTo(Fruit f) // sorting the color
{
return this.color.compareTo(f.color);
}
#Override public String toString()
{
return (name + " is: " + color);
}
} // end of Fruit class
I prefer this process:
public class SortUtil
{
public static <T> List<T> sort(List<T> list, String sortByProperty)
{
Collections.sort(list, new BeanComparator(sortByProperty));
return list;
}
}
List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate");
If you list of objects has a property called startDate, you call use this over and over. You can even chain them startDate.time.
This requires your object to be Comparable which means you need a compareTo, equals, and hashCode implementation.
Yes, it could be faster... But now you don't have to make a new Comparator for each type of sort. If you can save on dev time and give up on runtime, you might go with this one.
using the java-8 stream api you can sort an ArrayList by:
Comparator<Person> birthdayComparator = Comparator.comparing(Person::getBirthday);
List<Person> sortedList = list.stream().sorted(birthdayComparator).collect(toList());
Using Java 8 use can define the Comparator in one line using Comparator.comparing()
Use any of the following way:
Option 1:
listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate));
Option 2:
Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate));
Your custom class can implement the "Comparable" interface, which requires an implementation of the CompareTo method. In the CompareTo method, you can then define what it means that an object is less than or more than the other object. So in your example, it can look something like this:
public class MyCustomClass implements Comparable<MyCustomClass>{
..........
#Override
public int compareTo(MyCustomClass a) {
if(this.getStartDate().before(a.getStartDate())){
return -1;
}else if(a.getStartDate().before(this.getStartDate())){
return 1;
}else {
return 0;
}
}
A negative number indicates that this is smaller than the object being compared to. A positive number indicates that this is larger than the compared to object and a Zero means that the objects are equal.
You can then use the collections.sort(myList) to sort your list without having to feed in a comparator. This method also has the advantage of having things sorted automatically if you use a sorted collection data structures like a TreeSet or a TreeMap.
You can check this article if you would like to read more about the Comparable interface (disclosure: I am the author ;) )
https://nullbeans.com/the-java-comparable-interface-automatic-sort-of-collections/
You could also use Springs PropertyComparator if you have just a String property path to the (nested) property you want to sort:
List<SomeObject> list = ...;
PropertyComparator<HitWithInfo> propertyComparator = new PropertyComparator<>(
"property.nested.myProperty", false, true);
list.sort(propertyComparator);
The drawback is, that this comparator silently ignores properties which does not exist or are not accessible and handles this as null value for comparison. This means, you should carefully test such a comparator or validate the existence of the property path somehow.
I have tried lots of different solutions available on internet but solution which works for me is available at below link.
https://www.java67.com/2017/07/how-to-sort-arraylist-of-objects-using.html

How to sort ArrayList having custom objects in java having no pojo class? [duplicate]

I read about sorting ArrayLists using a Comparator but in all of the examples people used compareTo which according to some research is a method for Strings.
I wanted to sort an ArrayList of custom objects by one of their properties: a Date object
(getStartDay()). Normally I compare them by item1.getStartDate().before(item2.getStartDate()) so I was wondering whether I could write something like:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...
}
Since Date implements Comparable, it has a compareTo method just like String does.
So your custom Comparator could look like this:
public class CustomComparator implements Comparator<MyObject> {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
The compare() method must return an int, so you couldn't directly return a boolean like you were planning to anyway.
Your sorting code would be just about like you wrote:
Collections.sort(Database.arrayList, new CustomComparator());
A slightly shorter way to write all this, if you don't need to reuse your comparator, is to write it as an inline anonymous class:
Collections.sort(Database.arrayList, new Comparator<MyObject>() {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
Since java-8
You can now write the last example in a shorter form by using a lambda expression for the Comparator:
Collections.sort(Database.arrayList,
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
And List has a sort(Comparator) method, so you can shorten this even further:
Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
This is such a common idiom that there's a built-in method to generate a Comparator for a class with a Comparable key:
Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));
All of these are equivalent forms.
Classes that has a natural sort order (a class Number, as an example) should implement the Comparable interface, whilst classes that has no natural sort order (a class Chair, as an example) should be provided with a Comparator (or an anonymous Comparator class).
Two examples:
public class Number implements Comparable<Number> {
private int value;
public Number(int value) { this.value = value; }
public int compareTo(Number anotherInstance) {
return this.value - anotherInstance.value;
}
}
public class Chair {
private int weight;
private int height;
public Chair(int weight, int height) {
this.weight = weight;
this.height = height;
}
/* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getWeight() - chair2.getWeight();
}
}
class ChairHeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getHeight() - chair2.getHeight();
}
}
Usage:
List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);
List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());
// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
public int compare(Chair chair1, Chair chair2) {
...
}
});
For sorting an ArrayList you could use the following code snippet:
Collections.sort(studList, new Comparator<Student>(){
public int compare(Student s1, Student s2) {
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
}
});
JAVA 8 lambda expression
Collections.sort(studList, (Student s1, Student s2) ->{
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});
OR
Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)
Yes, you can. There are two options with comparing items, the Comparable interface, and the Comparator interface.
Both of these interfaces allow for different behavior. Comparable allows you to make the object act like you just described Strings (in fact, String implements Comparable). The second, Comparator, allows you to do what you are asking to do. You would do it like this:
Collections.sort(myArrayList, new MyComparator());
That will cause the Collections.sort method to use your comparator for it's sorting mechanism. If the objects in the ArrayList implement comparable, you can instead do something like this:
Collections.sort(myArrayList);
The Collections class contains a number of these useful, common tools.
With Java 8 you can use a method reference for your comparator:
import static java.util.Comparator.comparing;
Collections.sort(list, comparing(MyObject::getStartDate));
Since technologies appear everyday, the answer will change in the time. I took a look at LambdaJ and seems very interesting.
You can try solving these tasks with LambdaJ. You can find it here: http://code.google.com/p/lambdaj/
Here you have an example:
Sort Iterative
List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
}
});
Sort with lambda
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
Of course, having this kind of beauty impacts in the performance (an average of 2 times), but can you find a more readable code?
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
public class test {
public static class Person {
public String name;
public int id;
public Date hireDate;
public Person(String iname, int iid, Date ihireDate) {
name = iname;
id = iid;
hireDate = ihireDate;
}
public String toString() {
return name + " " + id + " " + hireDate.toString();
}
// Comparator
public static class CompId implements Comparator<Person> {
#Override
public int compare(Person arg0, Person arg1) {
return arg0.id - arg1.id;
}
}
public static class CompDate implements Comparator<Person> {
private int mod = 1;
public CompDate(boolean desc) {
if (desc) mod =-1;
}
#Override
public int compare(Person arg0, Person arg1) {
return mod*arg0.hireDate.compareTo(arg1.hireDate);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
ArrayList<Person> people;
people = new ArrayList<Person>();
try {
people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Collections.sort(people, new Person.CompId());
System.out.println("BY ID");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(false));
System.out.println("BY Date asc");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(true));
System.out.println("BY Date desc");
for (Person p : people) {
System.out.println(p.toString());
}
}
}
Function & method reference
The Collections.sort method can sort a List using a Comparator you pass. That Comparator can be implemented using the Comparator.comparing method where you can pass a method reference as the necessary Function. Fortunately, the actual code is much simpler and shorter than this description.
For Java 8:
Collections.sort(list, comparing(ClassName::getName));
or
Collections.sort(list, comparing(ClassName::getName).reversed());
Another way is
Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder())));
Best easy way with JAVA 8 is for English Alphabetic sort
Class Implementation
public class NewspaperClass implements Comparable<NewspaperClass>{
public String name;
#Override
public int compareTo(NewspaperClass another) {
return name.compareTo(another.name);
}
}
Sort
Collections.sort(Your List);
If you want to sort for alphabet that contains non English characters you can use Locale... Below code use Turkish character sort...
Class Implementation
public class NewspaperClass implements Comparator<NewspaperClass> {
public String name;
public Boolean isUserNewspaper=false;
private Collator trCollator = Collator.getInstance(new Locale("tr_TR"));
#Override
public int compare(NewspaperClass lhs, NewspaperClass rhs) {
trCollator.setStrength(Collator.PRIMARY);
return trCollator.compare(lhs.name,rhs.name);
}
}
Sort
Collections.sort(your array list,new NewspaperClass());
You can Sort using java 8
yourList.sort(Comparator.comparing(Classname::getName));
or
yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue)));
From Java 8 and onward we don't have to use Collections.sort() directly. List interface has a default sort() method:
List<User> users = Arrays.asList(user1,user2,user3);
users.sort( (u1, u2) -> {
return u1.getFirstName.compareTo(u2.getFirstName());});
See http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html.
Java 8 Lambda shortens the sort.
Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));
You can use the Bean Comparator to sort on any property in your custom class.
Yes, that's possible for instance in this answer I sort by the property v of the class IndexValue
// Sorting by property v using a custom comparator.
Arrays.sort( array, new Comparator<IndexValue>(){
public int compare( IndexValue a, IndexValue b ){
return a.v - b.v;
}
});
If you notice here I'm creating a anonymous inner class ( which is the Java for closures ) and passing it directly to the sort method of the class Arrays
Your object may also implement Comparable ( that's what String and most of the core libraries in Java does ) but that would define the "natural sort order" of the class it self, and doesn't let you plug new ones.
I found most if not all of these answers rely on the underlying class (Object) to implement comparable or to have a helper comparable interface.
Not with my solution! The following code lets you compare object's field by knowing their string name. You could easily modify it not to use the name, but then you need to expose it or construct one of the Objects you want to compare against.
Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));
public class ReflectiveComparator {
public class FieldComparator implements Comparator<Object> {
private String fieldName;
public FieldComparator(String fieldName){
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable object1FieldValue = (Comparable) field.get(object1);
Comparable object2FieldValue = (Comparable) field.get(object2);
return object1FieldValue.compareTo(object2FieldValue);
}catch (Exception e){}
return 0;
}
}
public class ListComparator implements Comparator<Object> {
private String fieldName;
public ListComparator(String fieldName) {
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable o1FieldValue = (Comparable) field.get(object1);
Comparable o2FieldValue = (Comparable) field.get(object2);
if (o1FieldValue == null){ return -1;}
if (o2FieldValue == null){ return 1;}
return o1FieldValue.compareTo(o2FieldValue);
} catch (NoSuchFieldException e) {
throw new IllegalStateException("Field doesn't exist", e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Field inaccessible", e);
}
}
}
}
You can try Guava Ordering:
Function<Item, Date> getStartDate = new Function<Item, Date>() {
public Date apply(Item item) {
return item.getStartDate();
}
};
List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate).
sortedCopy(items);
Well if you using Java 8 or older version Here is the Best solution.
Collections.sort(studentList, Comparator.comparing(Student::getCgpa).reversed().thenComparing(Student:: getFname).thenComparing(Student::getId));
In this case, it will first sort with 'getCgpa' first and for the second part it will sort with getFname and getId. Which is field into the pojo class.
your customComparator class must implement java.util.Comparator in order to be used.
it must also overide compare() AND equals()
compare() must answer the question: Is object 1 less than, equal to or greater than object 2?
full docs: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html
This code snippets might be useful. If you want to sort an Object
in my case I want to sort by VolumeName:
public List<Volume> getSortedVolumes() throws SystemException {
List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
Collections.sort(volumes, new Comparator<Volume>() {
public int compare(Volume o1, Volume o2) {
Volume p1 = (Volume) o1;
Volume p2 = (Volume) o2;
return p1.getVolumeName().compareToIgnoreCase(
p2.getVolumeName());
}
});
return volumes;
}
This works. I use it in my jsp.
With this library here you can sort the list of custom objects on multiple columns. The library uses version 8.0 features. Sample is also available there. Here is a sample to do
SortKeys sortKeys = new SortKeys();
sortKeys.addField("firstName")
.addField("age", true); // This (true) will sort the age descending
// Other ways to specify a property to the sorter are
// .addField("lastName", String.class);
// .addField("dob", Date.class, true);
// Instantiate a ListSorter
ListSorter listSorter = new ListSorter();
// Pass the data to sort (listToSort) and the "by keys" to sort (sortKeys)
List sortedList = (List<Person>) listSorter.sortList(listToSort, sortKeys);
You can have a look into this presentation hold at the Java Forum in Stuttgart Germany in 2016.
Only a few slides use German language, 99% of the content is "English based" Java source code; like
someCollection.sort(
OurCustomComparator
.comparing(Person::getName)
.thenComparing(Person::getId)
);
where OurCustomComparator is using default methods (and other interesting ideas). As shown, leading to very concise code to pick some getter method for sorting; and super simple chaining (or reversing) of sort criteria.
If you are into java8, you find a lot of material there to get you started.
New since 1.8 is a List.sort() method instead of using the Collection.sort()
so you directly call mylistcontainer.sort()
Here is a code snippet which demonstrates the List.sort() feature:
List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Kiwi","green",40));
fruits.add(new Fruit("Banana","yellow",100));
fruits.add(new Fruit("Apple","mixed green,red",120));
fruits.add(new Fruit("Cherry","red",10));
// a) using an existing compareto() method
fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName()));
System.out.println("Using String.compareTo(): " + fruits);
//Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green]
// b) Using a comparable class
fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2));
System.out.println("Using a Comparable Fruit class (sort by color): " + fruits);
// Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow]
The Fruit class is:
public class Fruit implements Comparable<Fruit>
{
private String name;
private String color;
private int quantity;
public Fruit(String name,String color,int quantity)
{ this.name = name; this.color = color; this.quantity = quantity; }
public String getFruitName() { return name; }
public String getColor() { return color; }
public int getQuantity() { return quantity; }
#Override public final int compareTo(Fruit f) // sorting the color
{
return this.color.compareTo(f.color);
}
#Override public String toString()
{
return (name + " is: " + color);
}
} // end of Fruit class
I prefer this process:
public class SortUtil
{
public static <T> List<T> sort(List<T> list, String sortByProperty)
{
Collections.sort(list, new BeanComparator(sortByProperty));
return list;
}
}
List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate");
If you list of objects has a property called startDate, you call use this over and over. You can even chain them startDate.time.
This requires your object to be Comparable which means you need a compareTo, equals, and hashCode implementation.
Yes, it could be faster... But now you don't have to make a new Comparator for each type of sort. If you can save on dev time and give up on runtime, you might go with this one.
using the java-8 stream api you can sort an ArrayList by:
Comparator<Person> birthdayComparator = Comparator.comparing(Person::getBirthday);
List<Person> sortedList = list.stream().sorted(birthdayComparator).collect(toList());
Using Java 8 use can define the Comparator in one line using Comparator.comparing()
Use any of the following way:
Option 1:
listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate));
Option 2:
Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate));
Your custom class can implement the "Comparable" interface, which requires an implementation of the CompareTo method. In the CompareTo method, you can then define what it means that an object is less than or more than the other object. So in your example, it can look something like this:
public class MyCustomClass implements Comparable<MyCustomClass>{
..........
#Override
public int compareTo(MyCustomClass a) {
if(this.getStartDate().before(a.getStartDate())){
return -1;
}else if(a.getStartDate().before(this.getStartDate())){
return 1;
}else {
return 0;
}
}
A negative number indicates that this is smaller than the object being compared to. A positive number indicates that this is larger than the compared to object and a Zero means that the objects are equal.
You can then use the collections.sort(myList) to sort your list without having to feed in a comparator. This method also has the advantage of having things sorted automatically if you use a sorted collection data structures like a TreeSet or a TreeMap.
You can check this article if you would like to read more about the Comparable interface (disclosure: I am the author ;) )
https://nullbeans.com/the-java-comparable-interface-automatic-sort-of-collections/
You could also use Springs PropertyComparator if you have just a String property path to the (nested) property you want to sort:
List<SomeObject> list = ...;
PropertyComparator<HitWithInfo> propertyComparator = new PropertyComparator<>(
"property.nested.myProperty", false, true);
list.sort(propertyComparator);
The drawback is, that this comparator silently ignores properties which does not exist or are not accessible and handles this as null value for comparison. This means, you should carefully test such a comparator or validate the existence of the property path somehow.
I have tried lots of different solutions available on internet but solution which works for me is available at below link.
https://www.java67.com/2017/07/how-to-sort-arraylist-of-objects-using.html

Sort ArrayList of custom Objects by property

I read about sorting ArrayLists using a Comparator but in all of the examples people used compareTo which according to some research is a method for Strings.
I wanted to sort an ArrayList of custom objects by one of their properties: a Date object
(getStartDay()). Normally I compare them by item1.getStartDate().before(item2.getStartDate()) so I was wondering whether I could write something like:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...
}
Since Date implements Comparable, it has a compareTo method just like String does.
So your custom Comparator could look like this:
public class CustomComparator implements Comparator<MyObject> {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
The compare() method must return an int, so you couldn't directly return a boolean like you were planning to anyway.
Your sorting code would be just about like you wrote:
Collections.sort(Database.arrayList, new CustomComparator());
A slightly shorter way to write all this, if you don't need to reuse your comparator, is to write it as an inline anonymous class:
Collections.sort(Database.arrayList, new Comparator<MyObject>() {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
Since java-8
You can now write the last example in a shorter form by using a lambda expression for the Comparator:
Collections.sort(Database.arrayList,
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
And List has a sort(Comparator) method, so you can shorten this even further:
Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
This is such a common idiom that there's a built-in method to generate a Comparator for a class with a Comparable key:
Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));
All of these are equivalent forms.
Classes that has a natural sort order (a class Number, as an example) should implement the Comparable interface, whilst classes that has no natural sort order (a class Chair, as an example) should be provided with a Comparator (or an anonymous Comparator class).
Two examples:
public class Number implements Comparable<Number> {
private int value;
public Number(int value) { this.value = value; }
public int compareTo(Number anotherInstance) {
return this.value - anotherInstance.value;
}
}
public class Chair {
private int weight;
private int height;
public Chair(int weight, int height) {
this.weight = weight;
this.height = height;
}
/* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getWeight() - chair2.getWeight();
}
}
class ChairHeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getHeight() - chair2.getHeight();
}
}
Usage:
List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);
List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());
// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
public int compare(Chair chair1, Chair chair2) {
...
}
});
For sorting an ArrayList you could use the following code snippet:
Collections.sort(studList, new Comparator<Student>(){
public int compare(Student s1, Student s2) {
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
}
});
JAVA 8 lambda expression
Collections.sort(studList, (Student s1, Student s2) ->{
return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});
OR
Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)
Yes, you can. There are two options with comparing items, the Comparable interface, and the Comparator interface.
Both of these interfaces allow for different behavior. Comparable allows you to make the object act like you just described Strings (in fact, String implements Comparable). The second, Comparator, allows you to do what you are asking to do. You would do it like this:
Collections.sort(myArrayList, new MyComparator());
That will cause the Collections.sort method to use your comparator for it's sorting mechanism. If the objects in the ArrayList implement comparable, you can instead do something like this:
Collections.sort(myArrayList);
The Collections class contains a number of these useful, common tools.
With Java 8 you can use a method reference for your comparator:
import static java.util.Comparator.comparing;
Collections.sort(list, comparing(MyObject::getStartDate));
Since technologies appear everyday, the answer will change in the time. I took a look at LambdaJ and seems very interesting.
You can try solving these tasks with LambdaJ. You can find it here: http://code.google.com/p/lambdaj/
Here you have an example:
Sort Iterative
List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
}
});
Sort with lambda
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
Of course, having this kind of beauty impacts in the performance (an average of 2 times), but can you find a more readable code?
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
public class test {
public static class Person {
public String name;
public int id;
public Date hireDate;
public Person(String iname, int iid, Date ihireDate) {
name = iname;
id = iid;
hireDate = ihireDate;
}
public String toString() {
return name + " " + id + " " + hireDate.toString();
}
// Comparator
public static class CompId implements Comparator<Person> {
#Override
public int compare(Person arg0, Person arg1) {
return arg0.id - arg1.id;
}
}
public static class CompDate implements Comparator<Person> {
private int mod = 1;
public CompDate(boolean desc) {
if (desc) mod =-1;
}
#Override
public int compare(Person arg0, Person arg1) {
return mod*arg0.hireDate.compareTo(arg1.hireDate);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
ArrayList<Person> people;
people = new ArrayList<Person>();
try {
people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Collections.sort(people, new Person.CompId());
System.out.println("BY ID");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(false));
System.out.println("BY Date asc");
for (Person p : people) {
System.out.println(p.toString());
}
Collections.sort(people, new Person.CompDate(true));
System.out.println("BY Date desc");
for (Person p : people) {
System.out.println(p.toString());
}
}
}
Function & method reference
The Collections.sort method can sort a List using a Comparator you pass. That Comparator can be implemented using the Comparator.comparing method where you can pass a method reference as the necessary Function. Fortunately, the actual code is much simpler and shorter than this description.
For Java 8:
Collections.sort(list, comparing(ClassName::getName));
or
Collections.sort(list, comparing(ClassName::getName).reversed());
Another way is
Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder())));
Best easy way with JAVA 8 is for English Alphabetic sort
Class Implementation
public class NewspaperClass implements Comparable<NewspaperClass>{
public String name;
#Override
public int compareTo(NewspaperClass another) {
return name.compareTo(another.name);
}
}
Sort
Collections.sort(Your List);
If you want to sort for alphabet that contains non English characters you can use Locale... Below code use Turkish character sort...
Class Implementation
public class NewspaperClass implements Comparator<NewspaperClass> {
public String name;
public Boolean isUserNewspaper=false;
private Collator trCollator = Collator.getInstance(new Locale("tr_TR"));
#Override
public int compare(NewspaperClass lhs, NewspaperClass rhs) {
trCollator.setStrength(Collator.PRIMARY);
return trCollator.compare(lhs.name,rhs.name);
}
}
Sort
Collections.sort(your array list,new NewspaperClass());
You can Sort using java 8
yourList.sort(Comparator.comparing(Classname::getName));
or
yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue)));
From Java 8 and onward we don't have to use Collections.sort() directly. List interface has a default sort() method:
List<User> users = Arrays.asList(user1,user2,user3);
users.sort( (u1, u2) -> {
return u1.getFirstName.compareTo(u2.getFirstName());});
See http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html.
Java 8 Lambda shortens the sort.
Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));
You can use the Bean Comparator to sort on any property in your custom class.
Yes, that's possible for instance in this answer I sort by the property v of the class IndexValue
// Sorting by property v using a custom comparator.
Arrays.sort( array, new Comparator<IndexValue>(){
public int compare( IndexValue a, IndexValue b ){
return a.v - b.v;
}
});
If you notice here I'm creating a anonymous inner class ( which is the Java for closures ) and passing it directly to the sort method of the class Arrays
Your object may also implement Comparable ( that's what String and most of the core libraries in Java does ) but that would define the "natural sort order" of the class it self, and doesn't let you plug new ones.
I found most if not all of these answers rely on the underlying class (Object) to implement comparable or to have a helper comparable interface.
Not with my solution! The following code lets you compare object's field by knowing their string name. You could easily modify it not to use the name, but then you need to expose it or construct one of the Objects you want to compare against.
Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));
public class ReflectiveComparator {
public class FieldComparator implements Comparator<Object> {
private String fieldName;
public FieldComparator(String fieldName){
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable object1FieldValue = (Comparable) field.get(object1);
Comparable object2FieldValue = (Comparable) field.get(object2);
return object1FieldValue.compareTo(object2FieldValue);
}catch (Exception e){}
return 0;
}
}
public class ListComparator implements Comparator<Object> {
private String fieldName;
public ListComparator(String fieldName) {
this.fieldName = fieldName;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable o1FieldValue = (Comparable) field.get(object1);
Comparable o2FieldValue = (Comparable) field.get(object2);
if (o1FieldValue == null){ return -1;}
if (o2FieldValue == null){ return 1;}
return o1FieldValue.compareTo(o2FieldValue);
} catch (NoSuchFieldException e) {
throw new IllegalStateException("Field doesn't exist", e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Field inaccessible", e);
}
}
}
}
You can try Guava Ordering:
Function<Item, Date> getStartDate = new Function<Item, Date>() {
public Date apply(Item item) {
return item.getStartDate();
}
};
List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate).
sortedCopy(items);
Well if you using Java 8 or older version Here is the Best solution.
Collections.sort(studentList, Comparator.comparing(Student::getCgpa).reversed().thenComparing(Student:: getFname).thenComparing(Student::getId));
In this case, it will first sort with 'getCgpa' first and for the second part it will sort with getFname and getId. Which is field into the pojo class.
your customComparator class must implement java.util.Comparator in order to be used.
it must also overide compare() AND equals()
compare() must answer the question: Is object 1 less than, equal to or greater than object 2?
full docs: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html
This code snippets might be useful. If you want to sort an Object
in my case I want to sort by VolumeName:
public List<Volume> getSortedVolumes() throws SystemException {
List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
Collections.sort(volumes, new Comparator<Volume>() {
public int compare(Volume o1, Volume o2) {
Volume p1 = (Volume) o1;
Volume p2 = (Volume) o2;
return p1.getVolumeName().compareToIgnoreCase(
p2.getVolumeName());
}
});
return volumes;
}
This works. I use it in my jsp.
With this library here you can sort the list of custom objects on multiple columns. The library uses version 8.0 features. Sample is also available there. Here is a sample to do
SortKeys sortKeys = new SortKeys();
sortKeys.addField("firstName")
.addField("age", true); // This (true) will sort the age descending
// Other ways to specify a property to the sorter are
// .addField("lastName", String.class);
// .addField("dob", Date.class, true);
// Instantiate a ListSorter
ListSorter listSorter = new ListSorter();
// Pass the data to sort (listToSort) and the "by keys" to sort (sortKeys)
List sortedList = (List<Person>) listSorter.sortList(listToSort, sortKeys);
You can have a look into this presentation hold at the Java Forum in Stuttgart Germany in 2016.
Only a few slides use German language, 99% of the content is "English based" Java source code; like
someCollection.sort(
OurCustomComparator
.comparing(Person::getName)
.thenComparing(Person::getId)
);
where OurCustomComparator is using default methods (and other interesting ideas). As shown, leading to very concise code to pick some getter method for sorting; and super simple chaining (or reversing) of sort criteria.
If you are into java8, you find a lot of material there to get you started.
New since 1.8 is a List.sort() method instead of using the Collection.sort()
so you directly call mylistcontainer.sort()
Here is a code snippet which demonstrates the List.sort() feature:
List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Kiwi","green",40));
fruits.add(new Fruit("Banana","yellow",100));
fruits.add(new Fruit("Apple","mixed green,red",120));
fruits.add(new Fruit("Cherry","red",10));
// a) using an existing compareto() method
fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName()));
System.out.println("Using String.compareTo(): " + fruits);
//Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green]
// b) Using a comparable class
fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2));
System.out.println("Using a Comparable Fruit class (sort by color): " + fruits);
// Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow]
The Fruit class is:
public class Fruit implements Comparable<Fruit>
{
private String name;
private String color;
private int quantity;
public Fruit(String name,String color,int quantity)
{ this.name = name; this.color = color; this.quantity = quantity; }
public String getFruitName() { return name; }
public String getColor() { return color; }
public int getQuantity() { return quantity; }
#Override public final int compareTo(Fruit f) // sorting the color
{
return this.color.compareTo(f.color);
}
#Override public String toString()
{
return (name + " is: " + color);
}
} // end of Fruit class
I prefer this process:
public class SortUtil
{
public static <T> List<T> sort(List<T> list, String sortByProperty)
{
Collections.sort(list, new BeanComparator(sortByProperty));
return list;
}
}
List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate");
If you list of objects has a property called startDate, you call use this over and over. You can even chain them startDate.time.
This requires your object to be Comparable which means you need a compareTo, equals, and hashCode implementation.
Yes, it could be faster... But now you don't have to make a new Comparator for each type of sort. If you can save on dev time and give up on runtime, you might go with this one.
using the java-8 stream api you can sort an ArrayList by:
Comparator<Person> birthdayComparator = Comparator.comparing(Person::getBirthday);
List<Person> sortedList = list.stream().sorted(birthdayComparator).collect(toList());
Using Java 8 use can define the Comparator in one line using Comparator.comparing()
Use any of the following way:
Option 1:
listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate));
Option 2:
Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate));
Your custom class can implement the "Comparable" interface, which requires an implementation of the CompareTo method. In the CompareTo method, you can then define what it means that an object is less than or more than the other object. So in your example, it can look something like this:
public class MyCustomClass implements Comparable<MyCustomClass>{
..........
#Override
public int compareTo(MyCustomClass a) {
if(this.getStartDate().before(a.getStartDate())){
return -1;
}else if(a.getStartDate().before(this.getStartDate())){
return 1;
}else {
return 0;
}
}
A negative number indicates that this is smaller than the object being compared to. A positive number indicates that this is larger than the compared to object and a Zero means that the objects are equal.
You can then use the collections.sort(myList) to sort your list without having to feed in a comparator. This method also has the advantage of having things sorted automatically if you use a sorted collection data structures like a TreeSet or a TreeMap.
You can check this article if you would like to read more about the Comparable interface (disclosure: I am the author ;) )
https://nullbeans.com/the-java-comparable-interface-automatic-sort-of-collections/
You could also use Springs PropertyComparator if you have just a String property path to the (nested) property you want to sort:
List<SomeObject> list = ...;
PropertyComparator<HitWithInfo> propertyComparator = new PropertyComparator<>(
"property.nested.myProperty", false, true);
list.sort(propertyComparator);
The drawback is, that this comparator silently ignores properties which does not exist or are not accessible and handles this as null value for comparison. This means, you should carefully test such a comparator or validate the existence of the property path somehow.
I have tried lots of different solutions available on internet but solution which works for me is available at below link.
https://www.java67.com/2017/07/how-to-sort-arraylist-of-objects-using.html

Categories