【问题标题】:Issue iterating through ArrayLists遍历 ArrayLists 的问题
【发布时间】:2011-11-19 22:32:06
【问题描述】:

我有两个问题。我这里有一个类型为ArrayList 的对象,对于这种情况,我们称之为"Car"

我做了两个:

Car car1 = new Car();
Car car2 = new Car();

我有一个向这些 Car 对象添加项目的功能:

car1.addPart("Front Wheels");
car1.addPart("Rear Wheels");
car1.addPart("Rear View Mirror");

car2.addPart("Rims");
car2.addPart("Steering Wheel");
car2.addPart("Bumper");

我需要一个名为 sameContents() 的函数,我可以在 car1 上调用它:

car1.sameContents(car2);

传入一个ArrayList类型的对象,并用car1检查它们是否具有相同的内容和相同的顺序。

public boolean sameContents(Car c) {
    ArrayList<String> other_car = c; // error: Type mismatch: 
                                    // cannot convert from Car to ArrayList<String>

    for (String c : this.parts) {
        System.out.println(c);
        for(String oc : other_car) { 
             // stuff
        }
    }
}

我似乎对这个有各种各样的问题。我无法在 foreach 循环中使用 other_car 变量。


第二个需要做的是transferContents

它被称为:

car1.transferContents(car2); 

car2 中的项目转移到car1,然后将car2 留空。我似乎无法让 ArrayList 在我认为我需要的 foreach 循环中再次工作。

 public void transfer(Car c) {
     // code for transfer method.
     // this.parts is the arraylist of car parts
     for (Car c: c) {
    this.parts.add(c);
      }
    // not sure how to set car2 to empty...
 }

【问题讨论】:

  • 好的……还有……你的问题是什么?到目前为止你有什么?你试过什么?
  • 你从 'sameContents' 方法确切的堆栈跟踪中得到了什么错误。如果它是空指针异常,那么还向我们展示参数 C 在传入之前是如何填充的。你为什么要循环 'this.parts'。
  • 好吧,那是因为 other_car 有 'Car' 对象而不是 'String' 对象。将 'for(String oc : other_car)' 更改为 'for(Car oc : other_car)'
  • @Shahzeb:没有意义“other_car 有 'Car' 对象而不是字符串......”我们仍然不知道 Car 类是什么,它扩展了什么,或者它包含什么。
  • @Hovercraft Full Of Eels 是的,我同意。德鲁,你的问题很有可能很好吃;这就是我们这么多人在这里的部分原因:) 但就像 Hover 说的那样,我们需要完整的画面。一开始我以为你的汽车对象有数组,但再读一遍,我发现你说的是数组。请在此处添加整个汽车类。是扩展 ArrayList 吗?

标签: java foreach arraylist


【解决方案1】:

给定一些List&lt;T&gt; foo,foreach 循环,例如:

for(T item : foo){
    // body
}

只是这个成语的简写语法:

Iterator<T> iter = foo.iterator();
while(iter.hasNext()){
    T item = iter.next();
    // body
}

要检查列表中是否还有更多项目,请调用iter.hasNext(),要检索下一个项目,请调用iter.next()

遍历两个列表可以通过保留大约 2 个迭代器来完成,检查两个迭代器是否有更多元素,然后检索这些元素。我们可以通过意识到不同长度的列表不能包含相同的元素(因为一个列表比另一个多)来消除不同长度列表上的一些边界条件。

根据您的描述,听起来Car 包含一个属性List&lt;String&gt; parts;,所以我们可以制定一个解决方案:

// different sizes, can't be equal
if(this.parts.size() != other.parts.size()){
    return false;
}

// get iterators
Iterator<String> left = this.parts.iterator();
Iterator<String> right = other.parts.iterator();

// safe to only check `left` because the lists are the same size
while(left.hasNext()){
    // check if left part is equal to the right part
    if(!left.next().equals(right.next())){
        // values are different, know at this
        // point they're not equal
        return false;
    }
}

// at this point, have exactly the same values
// in the same order.
return true;

至于您的transferContents 方法,您的想法是正确的,但是您不能迭代Car,您需要迭代List&lt;String&gt; parts。要删除单个部分,您可以使用remove() 方法,调用类似于add 方法,或者要删除所有元素,您可以调用clear()

把这些放在一起:

for (String part : c.parts) {
    this.parts.add(part);
}
c.parts.clear();

【讨论】:

    【解决方案2】:

    您可以依靠 java api 来完成您需要的所有工作。 ArrayList equals 方法在比较两个列表时检查顺序。 您可以使用 removeAll() 和 addAll() 方法来传输内容。

    public class Car {
    
        private final List<String> parts = new ArrayList<String>();
    
        public void addPart(String p) {
            parts.add(p);
        }
    
        public boolean sameContents(Car c) {
            return this.parts.equals(c.parts);
        }
    
        public void transfer(Car c) {
            final List<String> temp = new ArrayList<String>(c.parts);
            temp.removeAll(this.parts);
            this.parts.addAll(temp);
            c.parts.clear();
        }
    }
    

    【讨论】:

      【解决方案3】:

      您的汽车不应该一个数组列表,而是一个。例如。像这样:

      class Car {
          ArrayList<String> parts;
          // ...
      }
      

      那么您的sameContents 方法可以简单地调用列表的.equals() 方法进行比较:

      public boolean sameParts(Car other) {
           return this.parts.equals(other.parts);
      }
      

      同样,如果要从另一辆车转移零件,请使用列表的方法将零件add 到您的列表中,然后clear 另一个列表。

      【讨论】:

        猜你喜欢
        • 2019-02-26
        • 2011-09-06
        • 1970-01-01
        • 2019-02-26
        • 2023-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多