Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behaviour: Java Comparator randomizes list entries

I'm curious. What could be the reason that a Comparator shuffles entries on each application start?

final static class ContactsListComparator implements Comparator
{                           
    public int compare(Object o1, Object o2)
    {
        if((o1.toString().compareTo(o2.toString()))<0)
        {
            return -1;
        }
        if((o1.toString().compareTo(o2.toString()))>0)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }    
}    

First App Start:

alt text

Second App Start

alt text

As mentioned in one the answer

The Comparator actually compares an custom object Contact

public class Contact 
{
  // Members
  private String _contactFirstName;
  private String _contactLastName;
  private long _contactLastModified;

// Constructor
public Contact()
{
    set_contactLastModified();
}

public Contact(String contactFirstName)
{
    _contactFirstName = contactFirstName;
    set_contactLastModified();
}

// Accessable Getters
public String get_contactFirstName() 
{
    return _contactFirstName;
}

public String get_contactLastName()
{
    return _contactLastName;
}

public long get_contactLastModified()
{
    return _contactLastModified;
}

public void set_contactLastModified()
{
    _contactLastModified = System.currentTimeMillis();
}
  }
like image 637
Henrik P. Hessel Avatar asked Jun 29 '26 23:06

Henrik P. Hessel


2 Answers

your toString method probably isn't overridden for your objects representing the contacts. It will return a hash string for those objects, which varies every time your app is run.

You can fix this either of two ways:

  • Override the toString() method in your Contact object to return the contact's name (1), or
  • Change the Comparator to Comparator<Contact> so it gets Contact objects as parameters (2)

for (1), add this to your Contact class:

@Override public String toString() {
    return get_contactFirstName();
}

for (2) you would end up with this Comparator implementation:

final static class ContactsListComparator implements Comparator<Contact> {                           
    public int compare(Contact o1, Contact o2) {
        return contact1.get_contactFirstName().compareTo(contact2.get_contactFirstName());
    }
}

you don't even need to check for the <0 or >0, but you can just return whatever the String comparison gives.

I would use:

final static class ContactsListComparator implements Comparator<Contact>
{
public int compare(Contact c1,Contact c2)
 {
 int i=c1.get_contactLastName().compareTo(c2.get_contactLastName());
 if(i!=0) return i;
 return c1.get_contactFirstName().compareTo(c2.get_contactFirstName());;
 }

}
like image 42
Pierre Avatar answered Jul 02 '26 12:07

Pierre



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!