Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue iterating through ArrayLists

I have two questions. I have an object here that is of type ArrayList, and for this case let's call it "Car".

I have made 2 of them:

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

I have a function to add items to those Car objects:

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

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

I need to have a function called sameContents() that I can call on car1:

car1.sameContents(car2);

which passes in an object of type ArrayList and checks it with car1 to see if they have the same contents and in the same order.

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

I seem to be having all sorts of issues with this one. I can't get the other_car variable to be used in a foreach loop.


The second one that needs to be done is transferContents.

It's called like:

car1.transferContents(car2); 

which transfers the items in car2 into car1 and then leaves car2 empty. I can't seem to get the ArrayList to work again in a foreach loop which is what I think I need.

 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...
 }
like image 558
Drew Bartlett Avatar asked Sep 19 '11 03:09

Drew Bartlett


1 Answers

Given some List<T> foo, foreach loops, e.g.:

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

are just a shorthand syntax for this idiom:

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

To check that there are more items in the list, you call iter.hasNext(), to retrieve the next item, you call iter.next().

Walking two lists can be done by keeping around 2 iterators, checking that both iterators have more elements, and then retrieving those elements. We can eliminate some boundary conditions on different length lists by realizing that different length lists cannot contain the same elements (since one list has more than the other).

From your description, it sounds like Car contains a property List<String> parts;, so we can formulate a solution as:

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

As for your transferContents method, you have the right idea, but you cannot iterate over the Car, you need to iterate over the List<String> parts. To remove individual parts, you can use remove() method, called like the add method, or to remove all elements, you can call clear()

Putting this together:

for (String part : c.parts) {
    this.parts.add(part);
}
c.parts.clear();
like image 199
Mark Elliot Avatar answered Nov 19 '22 06:11

Mark Elliot