简体   繁体   中英

How do I merge two objects in Java?

For my homework assignment I need to merge two objects in Java. I have to create a method void mergeTrains(Train other) that will add all of the locomotives and cars from the other train to the current train. So after calling train1.mergeTrains(train2) the parameter train will have no cars and no locomotives when done. They will all have been added to train1.

We have to then use JUnit to check to see if the arrays and locomotives were merged correctly. Here is what I have so far:

public class Train {

    // data members
    private String trainName;
    private int numOfLocomotives;
    private int[] freightCars;

    // constructor
    public Train (String trainName, int numOfLocomotives) {
        this.trainName = trainName;
        this.numOfLocomotives = numOfLocomotives;
    }

    public int getNumOfLocomotives() {
        return numOfLocomotives;
    }

    public void setNumOfLocomotives(int numOfLocomotives) {
        if (numOfLocomotives < 0) {
            System.out.println("Error. Locomotives can't be set to less than 0.");
            return;
        } else {
            this.numOfLocomotives = numOfLocomotives;
        }
    }

    public int[] getFreightCars(int... freightCars) {
        if (freightCars == null) {
            System.out.println("There are no freight cars in the list.");
            return freightCars;
        } else {
            return freightCars;
        }
    }

    public int[] removeAllCars(int...freightCars) {
        freightCars = null;
        return freightCars;
    }

    public int[] addCars(int...weights) {
        int count = 0;
        int[] freightCars = {10, 20, 30}; // used to check if method functions correctly
        int[] newTrain = new int[freightCars.length + weights.length];
        for (int i = 0; i < freightCars.length; i++) {
            newTrain[i] = freightCars[i];
            count++;
        }
        for (int j = 0; j < weights.length; j++) {
            newTrain[count++] = weights[j];
        }
        for (int i = 0; i < newTrain.length; i++) {
            System.out.print(newTrain[i] + " ");
        }
        return newTrain;
    }

    public void mergeTrains(Train other) {
        this.numOfLocomotives = this.numOfLocomotives + other.numOfLocomotives;
        other.numOfLocomotives = 0;

    }

And here is my JUnit test class:

class TestTrain {

    int[] train1Cars = {10, 20, 30};
    int[] train2Cars = {4, 11, 15};
    int[] mergedTrain = {10, 20, 30, 4, 11, 15};

    @Test
    void testRemoveCars() {
        Train t1 = new Train("Thomas", 2);
        assertArrayEquals(t1.removeAllCars(train1Cars), null);
    }

    @Test
    void testAddCars() {
        Train t1 = new Train ("Thomas", 2);
        assertArrayEquals(t1.addCars(train2Cars), mergedTrain);
    }

    @Test
    void testMergeTrains() {
        Train t1 = new Train ("Thomas", 1);
        Train other = new Train ("Rob", 4);
    }
}

Basically I need to figure what am I supposed to do with the Train other parameter. And then how do I test that using JUnit. I think I have it correct with changing the locomotives in the mergeTrains method but I also don't know how to check for that in JUnit.

I would think that when you merge one train into the other, you add the locomotives from train2 to train1 and then you add the freight cars from the array in train2 to the array in train1. This latter step will involve copying arrays. I recommend you look at the Java method System.arraycopy() to do this.

To do both of these operations you must use the instance of the Train passed to the merge method.

I would also expect the locomotives and engines in train2 to be zeroed out. A new, empty array could be use to replace the old array. But it depends on how your instructor expects you to indicate that.

The values in the arrays are an implementation detail. Let's look instead at the state of each train.

For example:

    @Test
    void can_add_a_car() {
        Train t1 = new Train("Thomas", 2);
        t1.addCars(1, 1, 1);
        assertEquals(t1.numberOfCars(), 3);
    }

So the class starts to look something like

public class Train {
    private ...instance variables ...

    public addCars(int... weights) { ... }
}

It would be nice to be able to remove a car too

@Test
void can_remove_a_car() {
    Train t1 = new Train("Thomas", 2);
    t1.addCars(1, 2, 3);
    t1.removeCar(2);
    assertEquals(t1.numberOfCars(), 2);
    assertEquals(t1.weight(), 3);
}

This might suggest a method like

public int removeCar(int position) {
    // TODO: move all the cars up by one
    return freightCars[position];
}

public int weight() {
    // sum the weights of the cars
}

Merging a car looks like this:

@Test
void can_merge_trains() {
    Train t1 = new Train("Thomas", 2);
    Train t2 = new Train("Rob", 2);
    t1.addCars(1, 1, 1)
    t2.addCars(1, 1, 1)
    t1.merge(t2);
    assertEquals(t1.numberOfCars(), 6);
    assertEquals(t2.numberOfCars(), 0);
}

We might implement this method like so:

public void mergeCars(Train other) {
    for(int k = other.numberOfCars() - 1; k >= 0; k--) {
        addCar(other.removeCar());
    }
}

You can add methods to add and remove locomotives as well and use those in mergeCars.

There may be more efficient ways to implement the array copy, rather than doing it one car at a time. You should be able to add bulk add and remove methods if performance becomes a problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM