Android-java- How to sort a list of objects by a certain value within the object
You should use Comparable instead of a Comparator if a default sort is what your looking for.
See here, this may be of some help - When should a class be Comparable and/or Comparator?
Try this -
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestSort {
public static void main(String args[]){
ToSort toSort1 = new ToSort(new Float(3), "3");
ToSort toSort2 = new ToSort(new Float(6), "6");
ToSort toSort3 = new ToSort(new Float(9), "9");
ToSort toSort4 = new ToSort(new Float(1), "1");
ToSort toSort5 = new ToSort(new Float(5), "5");
ToSort toSort6 = new ToSort(new Float(0), "0");
ToSort toSort7 = new ToSort(new Float(3), "3");
ToSort toSort8 = new ToSort(new Float(-3), "-3");
List<ToSort> sortList = new ArrayList<ToSort>();
sortList.add(toSort1);
sortList.add(toSort2);
sortList.add(toSort3);
sortList.add(toSort4);
sortList.add(toSort5);
sortList.add(toSort6);
sortList.add(toSort7);
sortList.add(toSort8);
Collections.sort(sortList);
for(ToSort toSort : sortList){
System.out.println(toSort.toString());
}
}
}
public class ToSort implements Comparable<ToSort> {
private Float val;
private String id;
public ToSort(Float val, String id){
this.val = val;
this.id = id;
}
@Override
public int compareTo(ToSort f) {
if (val.floatValue() > f.val.floatValue()) {
return 1;
}
else if (val.floatValue() < f.val.floatValue()) {
return -1;
}
else {
return 0;
}
}
@Override
public String toString(){
return this.id;
}
}
sort List of Object by one of Object's field
You need to implement a Custom Comparator like the following
public class ContactComparator implements Comparator<Contact> {
public int compare(Contact contact1, Contact contact2) {
//In the following line you set the criterion,
//which is the name of Contact in my example scenario
return contact1.getName().compareTo(contact2.getName());
}
}
Then all you need is to call it like this (anywhere in your code where you need to have your contacts sorted):
Collections.sort(myContacts, new ContactComparator());
myContacts is the list of Contact objects you need to sort (you name it list in your question).
Sorting List of objects in android
Use Collection.sort
and pass your own implementation of Comparator
Example:
List<Country> items = new ArrayList<Country>();
.....
Collections.sort(items, new Comparator<Country>() {
@Override
public int compare(Country o1, Country o2) {
return Double.compare(o1.getDistance(), o2.getDistance());
}
});
Sorting a listview of objects with value of the object itself - After a Query in DB
Perhaps this could help
class myAdapter extends BaseAdapter {
private List<String> mList;
public void setList(List<String> list){
mList.clear();
mList.addAll(list);
sortMyList();
}
private void sortMyList() {
//Do sorting of the list
notifyDataSetChanged();
}
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
}
You could then call
myAdapter.setList(list);
which will set the list and sort it.
Sorting:
Collections.sort(empList, new Comparator<Employee>(){
public int compare(Employee emp1, Employee emp2) {
return emp1.getFirstName().compareToIgnoreCase(emp2.getFirstName());
}
});
taken from here: Android-java- How to sort a list of objects by a certain value within the object
Sorting list of custom objects wrt a property in android studio (API level problem)
You could create Long
objects for the times and compare them directly:
Collections.sort(news, new Comparator<NewsItem>() {
@Override
public int compare(NewsItem newsItem1, NewsItem newsItem2) {
return Long.valueOf(newsItem2.getUpdateTime()).compareTo(
Long.valueOf(newsItem1.getUpdateTime()));
}
});
As a side note - API level 16 is quite outdated, and you may want to consider upgrading your requirements.
Sorting List of Objects by long property
Look at the definition of Long#compare
:
public static int compare(long x, long y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
Similary, you simply can return 1
if the value greater than the other value, 0
if equals and -1
if less than:
Collections.sort(priceList, new Comparator<MyObject>() {
@Override
public int compare(MyObject o1, MyObject o2) {
return (o1.getPrice() < o2.getPrice()) ? -1 : ((o1.getPrice() == o2.getPrice()) ? 0 :1 );
});
Sort a Java collection object based on one field in it
here is my "1liner":
Collections.sort(agentDtoList, new Comparator<AgentSummaryDTO>(){
public int compare(AgentSummaryDTO o1, AgentSummaryDTO o2){
return o1.getCustomerCount() - o2.getCustomerCount();
}
});
UPDATE for Java 8:
For int datatype
Collections.sort(agentDtoList, (o1, o2) -> o1.getCustomerCount() - o2.getCustomerCount());
or even:
Collections.sort(agentDtoList, Comparator.comparing(AgentSummaryDTO::getCustomerCount));
For String datatype (as in comment)
Collections.sort(list, (o1, o2) -> (o1.getAgentName().compareTo(o2.getAgentName())));
..it expects getter AgentSummaryDTO.getCustomerCount()
Java sort array of objects by integer field and if those are identical then sort by another integer value
Try to customize the compare
method.
e.g.
if(o1.getPriority() != o2.getPriority())
return Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority());
if(o1.getTime() != o2.getTime())
return Integer.valueOf(o1.getTime()).compareTo(o2.getTime());
return 0; //they are equal with all fields
Android - java - how to sort a list of object byan GregorianCalendar argument
EDIT I completly overhauled my answer in response to the new edit on your question.
The problem is that for each Evento
that populates your listEventos1
, you're using the same Calendar
(variable name day
). You're doing this:
list.add(setEvento(day, "Certain Tuesday”, "do this"));
And then this:
day.add(Calendar.DAY_OF_MONTH, 1);
list.add(setEvento(day, "Certain Wendsday”, "do that"));
But what the call to Calendar#add
does is it
Adds or subtracts the specified amount of time to the given calendar
field, based on the calendar's rules.
In other words, Calendar
is a mutable class, i.e. it can change states, unlike a String
, which is immutable and will always be the same. Don't worry, you're not the first to make that mistake, and that's partly why Java introduced a new Date API (more precisely, it's because that made the classes not thread-safe).
So in other words, whenever you're calling the Calendar#add
method, all objects in listEventos1
change, because they all contain the same instance of Calendar
. For a really good example of why this happens, see this answer.
One way to verify this is to add a supplementary check in your Comparator
by using the ==
operator. ==
will return true if the two variables point to the same instance:
Collections.sort(listEventosAll, new Comparator<Evento> (){
public int compare(Evento evento1, Evento evento2) {
if(evento1.date.getTime() == evento2.date.getTime())
System.out.println("Warning! Two references pointing to the same object!");
if (evento1.date.getTime() == null || evento2.date.getTime() == null)
return 0;
return evento1.date.getTime().compareTo(evento2.date.getTime());
}
Running this with your current code should output a bunch of warnings.
Another tidbit of information: according to the Javadoc of Comparator
, Comparator#compare
should throw a NullPointerException
if one of the arguments is null
.
SOLUTION
To fix this problem, you need to pass different instances of Calendar
at each call of setEvento
. Some classes, such as those in the Collection API possess copy constructors, that is, constructors that will take an object as an argument, and return a new object with exactly the same values. Calendar
doesn't implement copy constructors, but it does however implement the Cloneable
interface, which means you can clone its objects.
Cloning is sometimes frowned upon in the Java world, but in this specific case it's a viable option.
So here's how to clone day
so that each time you call Evento
, it points to a new object (this is your listEventos1
method):
list.add(setEvento(day, "Certain Tuesday", " do this "));
day = (Calendar) day.clone(); //This is what I added
day.add(Calendar.DAY_OF_MONTH, 1);
Naturally, repeat this for every object your insert.
NOTE: btw, some quotation marks in your code are closing English quotation marks (”
) instead of double quotes ("
). This will break your code.
OTHER NOTE: You're not using the inheritance mechanism correctly, and your code could be simplified by using Evento
as a Calendar
itself. But that's for another day.
Related Topics
How to Get Specific Pushedid in Firebase
Detect Touch Press VS Long Press VS Movement
Moving from Jdk 1.7 to Jdk 1.8 on Ubuntu
Differences Between Exception and Error
Is It Possible in Java to Access Private Fields via Reflection
What Is the Main Difference Between Inheritance and Polymorphism
Handling MySQL Datetimes and Timestamps in Java
How to Convert the Following JSON String to Java Object
How to Read Jsch Command Output
How to Check Certificate Name and Alias in Keystore Files
Android: How to Gain Root Access in an Android Application
How to Downsample Images Within PDF File
How to Create a Directory in Java
Why Java Inner Classes Require "Final" Outer Instance Variables
How to Decompile a Whole Jar File
Connection to Db Dies After >4<24 in Spring-Boot JPA Hibernate