-6

演習では、特定の名前パラメーターに一致するすべてのユーザーをリストコレクションから削除する必要があります。ソリューションでは、for-eachループを使用する必要があります。


以下に示すソリューションは、コンパイル時エラーをスローしませんが、ソリューションの正しさを検証するために実行される単体テストの1つに合格しません。

これが私がこれまでに試したことです:

public ArrayList<Person> people;
public void remove(String name){
    for(Person i : people){
        if (people.contains(name)){
            people.remove(i);
        }
    }
}
4

5 に答える 5

4

どのテストに合格しませんか?

しかし、コードを見てみましょう:

param'name'を取得します。次に、個人のリストを繰り返し処理します。現在の人は私です。各ステップで、リストに名前(文字列)が含まれているかどうかを確認します。うーん。

containsは、リスト全体に何かが含まれているかどうかを尋ねます。これは、リスト内の要素のタイプと一致する必要がありますね。

しかし、繰り返しながら、各人(i)に、人の名前が「名前」であるかどうかを尋ねることができます。

if (i.name.equals (name)) // or 
if (i.getName ().equals (name))

その間に削除を繰り返すことは、世話をするための別の問題です。

多くの噂があり、多くの人が問題を監督しているように見えたので、私はインターレーターを使用するのとは異なる解決策を持っています:削除する候補を収集し、最終的にブラックリスト全体をまとめて差し引きます:

public void remove (String name) 
{
    List <Person> blacklist = new ArrayList <Person> ();
    for (Person p : people) 
    {
        if (p.getName ().equals (name))
        {
            blacklist.add (p);
        }
    }
    people.removeAll (blacklist);
}
于 2011-04-27T23:04:54.150 に答える
1

getName()これには、個人クラスにもちろんという名前のメソッドが必要です。または、 equals メソッドをオーバーライドすることもできますが、この回答のコメントに記載されている欠点に注意してください。

public void remove(String name) {
for (Person person : people) {
    if (person.getName().equals(name)) {
        people.remove(person);
    }
}

このコレクションに指定された要素が含まれている場合は true を返します。より正式には、このコレクションに (o==null ? e==null : o.equals(e)) となる要素 e が少なくとも 1 つ含まれている場合にのみ true を返します。

http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html#contains(java.lang.Object )

于 2011-04-27T23:22:53.660 に答える
1

編集:

これまでに投稿された他のすべての回答と同様に、私の最初の回答 (行の下) は実際にはWRONGです。私は少しテストを行いました(以下)... foreachループの根底にあるイテレータですべてConcurrentModificationExceptionを引き起こしています。今、あなたのための落とし穴があります! はぁ。

package forums;

import java.util.List;
import java.util.ArrayList;

class Person
{
  private final String name;
  private final int age;
  Person(String name, int age) {
    this.name=name;
    this.age=age;
  }
  public String getName() { return name; }
  public int getAge() { return age; }
  public String toString() { return name + " " + age; }
}

public class PeopleTest
{
  public List<Person> people;

  public void remove(String name)
  {
    for ( int i=0; i<people.size(); i++ ) {
      Person person = people.get(i);
      if (person.getName().equals(name)) {
        people.remove(person);
        i--;
      }
    }
  }

  public void badRemove(String name)
  {
    for ( Person person : people ) {
      if (person.getName().equals(name)) {
        people.remove(person);
      }
    }
  }

  public void printAll(String message) {
    System.out.println(message);
    for ( Person person : people ) {
      System.out.println("  " + person);
    }
  }


  public void run() 
  {
    // setup
    people = new ArrayList<Person>(5);
    Person dave, kelly, jack, jill, xavier;
    people.add(dave=new Person("Dave", 36));
    people.add(kelly=new Person("Kelly", 25));
    people.add(jack=new Person("Jack", 42));
    people.add(jill=new Person("Jill", 19));
    xavier = new Person("Xavier", 136);

    badRemove("Dave");

    // before image
    assert people.size() == 4;
    printAll("the before list");

    // operation 1
    assert !people.contains(xavier);
    remove("Xavier"); // a no-op.
    assert people.size() == 4;
    assert !people.contains(xavier);

    // operation 2
    assert people.contains(jill);
    remove("Jill"); // she smells!

    // after image
    printAll("the after list");
    assert people.size() == 3;
    assert people.contains(dave);
    assert people.contains(kelly);
    assert people.contains(jack);
    assert !people.contains(jill);
  }

  public static void main(String[] args) {
    try {
      new PeopleTest().run();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}

出力

C:\Java\home\src\forums>"C:\Program Files\Java\jdk1.6.0_16\bin\java.exe" -Xms4m -Xmx256m -enableassertions -cp c:\java\home\src;C:\Java\home\classes; forums.PeopleTest
java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at forums.PeopleTest.badRemove(PeopleTest.java:36)
        at forums.PeopleTest.run(PeopleTest.java:62)
        at forums.PeopleTest.main(PeopleTest.java:89)

お前、

この答えは間違っています。無視してください!!!

代わりにhttp://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html#remove%28java.lang.Object%29を使用することをお勧めします。

何かのようなもの:

public ArrayList<Person> people;

public void remove(String name) {
  for ( Person person : people ) {
    if (person.getName().equals(name)) {
      people.remove(person);
    }
  }
}

... Person にgetName文字列を返すメソッドがあると仮定します。

乾杯。キース。

于 2011-04-27T23:24:52.157 に答える
1

リストから削除しようとしている場合は、for-each ループを使用しないでください。

the for-each loop hides the iterator, so you cannot call remove. 

(ドキュメンテーションから)

代わりに標準イテレータとそのメソッドを使用してください。remove

于 2011-04-27T23:15:50.963 に答える
-3

Person クラスに名前を保存する方法はわかりませんが、このようなことができるかもしれません。people 配列リストに i 番目の要素を保存することを忘れないでください

public ArrayList<Person> people;

public void remove(String name){
        for(Person i : people){
            if (i.getName().equals(name)){
                people.remove(i);
            }
        }
    }
于 2011-04-27T23:00:10.400 に答える