练习要求从List集合中删除匹配给定名称参数的所有人。解决方案必须使用for-each循环。
下面给出的解决方案不会给我带来任何编译时错误,但是它无法通过运行的单元测试之一来验证解决方案的正确性。
这是我到目前为止所尝试的内容:
public ArrayList<Person> people;
public void remove(String name){
for(Person i : people){
if (people.contains(name)){
people.remove(i);
}
}
}
答案 0 :(得分:4)
哪个测试未通过?
但是让我们来看看代码:
你得到一个参数'name'。然后迭代一个人员列表。现在的人就是我。在每个步骤中,您询问列表,它是否包含名称(这是一个字符串)。嗯。
包含询问整个列表,是否包含某些东西 - 这个东西应该匹配列表中元素的类型,不应该吗?
但是在迭代时,您可以询问每个人(i),人名是否是“姓名”。
if (i.name.equals (name)) // or
if (i.getName ().equals (name))
迭代同时删除是另一个问题,要照顾。
由于有很多谣言,并且很多人似乎都在监督这个问题,我有一个不同的解决方案,而不是使用一个交互者:收集候选人进行删除,并将整个黑名单最终减为一堆:< / p>
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);
}
答案 1 :(得分:1)
如果要从列表中删除,请不要使用for-each循环:
the for-each loop hides the iterator, so you cannot call remove.
改为使用standard iterator及其remove
方法。
答案 2 :(得分:1)
这将要求您的person类当然有一个名为getName()
的方法。或者你可以覆盖equals方法,但要注意这个答案的评论中所述的缺点。
public void remove(String name) {
for (Person person : people) {
if (person.getName().equals(name)) {
people.remove(person);
}
}
如果此集合返回true 包含指定的元素。更多 正式地,当且仅当如果,则返回true 此集合包含至少一个 元素e使得(o == null?e == null :o.equals(e))。
http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html#contains(java.lang.Object)
答案 3 :(得分:1)
修改强>
我的第一个答案(在线下)实际上是错误,就像到目前为止发布的所有其他答案一样。我做了一点测试(下面)...我们在迭代器中导致了一个 ConcurrentModificationException ,它是foreach循环的基础。现在有一个问题!叹。
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
方法,它会返回一个字符串。
干杯。基思。
答案 4 :(得分:-3)
我不知道你如何在Person类上存储名称,但也许你可以做这样的事情。请记住,我将iith元素存储在人员arraylist上,因此每次迭代都需要检查当前人员的姓名以检查是否需要删除它
public ArrayList<Person> people;
public void remove(String name){
for(Person i : people){
if (i.getName().equals(name)){
people.remove(i);
}
}
}