简体   繁体   English

奇怪的行为:Java Comparator随机化列表条目

[英]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: 首次应用开始:

替代文字

Second App Start 第二个App Start

替代文字

As mentioned in one the answer 如答案所述

The Comparator actually compares an custom object Contact 比较器实际上比较了自定义对象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();
}
  }

your toString method probably isn't overridden for your objects representing the contacts. 您的toString方法可能不会覆盖表示联系人的对象。 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 覆盖Contact对象中的toString()方法以返回联系人的姓名(1)或
  • Change the Comparator to Comparator<Contact> so it gets Contact objects as parameters (2) Comparator更改为Comparator<Contact>以便将Contact对象作为参数获取(2)

for (1), add this to your Contact class: 对于(1),将其添加到您的Contact类:

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

for (2) you would end up with this Comparator implementation: 对于(2)你最终会得到这个比较器的实现:

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. 你甚至不需要检查<0或> 0,但你可以返回字符串比较给出的任何内容。

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());;
 }

}

Your first example is basically the same as 你的第一个例子与...基本相同

final static class ContactsListComparator implements Comparator {                           
    public int compare(Object o1, Object o2) {
        return o1.toString().compareTo(o2.toString());
    }    
}

This would work if you override toString() like 如果你重写toString()就行了

public String toString() {
     return _contactFirstName + ' ' + _contactLastName;
}

However, a comparator which compares the intended fields is better as has been suggested. 然而,如所建议的那样,比较预期场的比较器更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM