2009-07-12 9 views
2

私は好奇心が強いです。コンパレータが各 アプリケーションのエントリをシャッフルする理由は何ですか?奇妙な振る舞い:Java Comparatorがリスト項目をランダム化

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

最初のアプリを起動:

alt text

第二のAppスタート

alt text

1つの回答で述べたように

コンパレータは、実際にカスタムオブジェクトを比較連絡先

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

もっとコードが必要です。このコンパレータはどのように使いましたか? – Pierre

+0

私は、toString()メソッドが何をしているかを詳しく見ていきます。例えば、オブジェクトのシリアルIDをリストするだけかもしれません。 –

答えて

14

あなたのtoStringメソッドは、おそらく連絡先を表すオブジェクトに対して上書きされません。これらのオブジェクトのハッシュ文字列が返されます。このハッシュ文字列は、アプリケーションが実行されるたびに変化します。

  • オーバーライド連絡先の名前を返すようにContactオブジェクト内toString()方法は、(1)、または
  • 変更ComparatorComparator<Contact>にそれがContactオブジェクトを取得します。

    次のいずれかの2つの方法のこの問題を解決することができます

    :パラメータ(2)(1)、あなたの連絡先クラスにこれを追加するための

として(2)あなたはこのコンパレータの実装で終わるだろうため10

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

:あなたも< 0または> 0をチェックする必要はありませんが、あなただけのどんな文字列の比較を返すことができ

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

与える。

+0

正しい! =)((ContactsListObject)o1).get_contactFirstName()。compareTo((ContactsListObject)o2).get_contactFirstName()) –

+0

スウィートキャッチ、ブラボー! – javamonkey79

2

私が使用します。

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

} 
+0

コンパレータは少なくともJRE 1.5が必要ですか? –

+0

はい、ジェネリックは1.5 – Jorn

+0

で導入されましたが、J2MEでは動作しません。醜いキャストに固執する必要があります! –

2

あなたの最初の例では、基本的には同じである

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

としてこれが働くだろうあなたはしかし、

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

のようにtoString()をオーバーライドしている場合示唆されているように、意図されたフィールドを比較するコンパレータが優れています。