2016-08-26 4 views
3

indexOfメソッドを使用してオブジェクトの位置を返すことができますが、これを検索するために連絡先の名前を渡したいだけですこれを行うには?arrayListのindexOfをcustomObjectで使用する

私は現在、このメソッドを持っていますHERESに

private static ArrayList<Contacts> contactList = new ArrayList<Contacts>(); 

public class Contacts { 
private String name; 
private String number; 


public Contacts(String name, String number) { 
    this.name = name; 
    this.number = number; 
} 

public String getName() { 
    return name; 
} 

public String getNumber() { 
    return number; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public void setNumber(String number) { 
    this.number = number; 
} 



public int findItem(String name) { 

    return contactList.indexOf(name); 
} 

答えて

1

リスト全体を経由せずにこれを実現する関数、I(n)は複雑さはO未満であると思う:

public int findItem(String name) 
    { 
     int max = contactList.size(); 

     //you might have to subtract this by one 
     //I'm not sure off the top 
     int descCnt = max; 


     for(int cnt = 0; cnt <= max/2; cnt++) 
     { 
      if(contactList.get(cnt).getName().equals(name)) return cnt; 
      if(contactList.get(descCnt).getName().equals(name)) return descCnt; 
      --descCnt; 
     } 

    } 
+0

いいえ、まだO(n)です。このような「最適化」は、リストのいずれかの端から項目を取得するとキャッシュのフェッチが増えるため、処理が遅くなる可能性があります。 –

+0

複雑さはO(n)です。あなたはforループの半分の反復をしているかもしれませんが、あなたはまだすべての要素を調べています。これは、全体を1つずつ反復するよりも優れていません。 – nasukkin

+0

私は参照してください。説明をありがとうございます。私は平均でこれが速く答えにあなたを得るように感じる? @AndyTurner –

0

あなたが求めるものはList#indexOf(Object)という契約にはないので、そうではありません。そのような方法でリストを作ってはいけません。

代わりに、比較的容易に行うことができる独自のメソッドを記述することができます。あなたのリストを繰り返して、指定された名前と一致する連絡先を見つけるだけです。

/** 
* Returns the List index of the Contact with the specified name. If no such 
* Contact is found, -1 will be returned. 
*/ 
public int findItem(String name) { 
    for (int i = 0; i < contactList.size(); i++) { 
     Contact contact = contactList.get(i); 
     if (null == contact) continue; 
     if (java.lang.Objects.equals(name, contact.getName())) return i; 
    } 
    return -1; 
} 
+0

@SamOrozcoだから?この質問は、パフォーマンスに関する懸念について言及していません。それでも、このメソッドは任意のArrayListを取得するのと同じくらい優れています。さて、もし配列が名前でソートされていれば、より魅力的な検索を行い、複雑さをO(ln(n))に減らすことができますが、複雑さの要求やソート可能性は言及されません。 – nasukkin

+0

私の以前のコメントについては申し訳ありませんが、私は混乱しました。 –

0

だけでみんなを追加するために、私はこのようにそれを行うことができました:

public void searchItem(String name) { 
    for(int i = 0; i < contactList.size(); i++) { 
     if(name.equals(contactList.get(i).getName())) { 
      System.out.println("Found " + name); 
      break; 
     } 
     else { 
      System.out.println("Could not find name!"); 
     } 
    } 
} 

私は大きなリストを持っていた場合は、これはかなり非効率的ではないでしょうか?これを行うより効率的な方法はありますか?

+0

効率的ではありませんか?アプリケーションでこのようなパフォーマンスの問題が発生していますか?書いたものを最適化することについて心配する必要がありますか?覚えておいてください:時期尚早最適化はすべての悪の根源です。ここで書いたことは、あなたのリストを検索するうまい方法です。 – nasukkin

+0

'contactList'は' ArrayList'なので、これは合理的に効率的です(アイテムを見つけるまで、 'Could not find name'をすべての反復で印刷することを除いて)。 'LinkedList'に変更した場合(例えば、' RandomAccess'リストの 'O(1)'と比較して)リスト検索が 'O(n) ArrayList')。 –

1

名前でContactsの検索をたくさん行っている場合は、インスタンスをMap<String, Contacts>に入れることができます。特定のタイプのMapは要件に応じて異なります。 HashMapで十分です。

contactMap.put(contacts.getName(), contacts); 

をしてから使用してマップ内の項目を検索:

代わりのcontactList.add(contacts)は、使用することができます

contactMap.get(someName); 

これはリストをスキャンするより検索を行うことが速くなります毎回、リストはO(n)と比較して、それぞれの検索がHashMapの場合はO(1)になります。ただし、より多くのメモリを使用します。


ところで、それは単一の接触を表しように、あなたのContactsクラスが見えますので、それは単数として指名されなければならない:Contact

また、あなたのfindメソッドは、現在のインスタンスメソッドとして宣言されています。

public int findItem(String name) { 

あなたが実際にContactsの別のインスタンスを見つけるために、Contactsのインスタンスを必要とするという意味します。その代わり、staticそれを宣言:

public static int findItem(String name) { 

を、あなたはインスタンスなしでそれを呼び出すことができます。

Contacts found = Contacts.find("name"); 
0

興味のある方。より良い方法は、オブジェクト内のequals()とhashcode()をオーバーライドすることです。 indexOfを適切な方法で使用してください。

あなたの等号は名前に基づいて同等性を判断することができるため、余分な不要なコードはすべて削除されます。

関連する問題