rls1982 rls1982 - 1 month ago 29
Java Question

Java: Return number added to Array

I'm writing a program in which I'm needing to return the number of reviews added to an array. Here is what I have so far.

package assignment;

import java.text.MessageFormat;
import java.util.Scanner;

import java.awt.Point;
import java.awt.Dimension;
import java.awt.Rectangle;

import java.time.LocalDate;

class Review {
public String reviewText;
public int numberOfStars;

public Review(String reviewText, int numberOfStars) {
this.reviewText=reviewText;
this.numberOfStars=numberOfStars;
}
}
class GameInfo {
private String title;
private Review[] reviews = new Review[10];
// need an array to keep the reviews; I suggest as below, but feel free to use something else
// your array needs to be able to contain *at least 10* reviews. My tests will not add more than 10 (later we'll see better collections)
// private Review[] reviews;
// can add any other fields; for example, one to keep track of how many reviews you actually have (your array may contain up to 10, but at any given time may have way less; even 0)

public GameInfo(String title) {
this.title=title;
this.reviews= reviews;
// you may want to initialize any other variables you create here
}

public String getTitle() {
return title;
}


// TODO - adds the review to the 'array' of reviews. You need to keep all reviews in an array
public void addReview(Review r) {
int i = 0;
while (i < this.reviews.length && this.reviews[i++] == null);
if (i < this.reviews.length) this.reviews[i] = r;
}
// TODO - returns the number of reviews which have been added to this GameInfo
public int getNumberOfReviews() {
int count = 0;
for (int i = 0; i < this.reviews.length; ++i) {
++count;
}
return count;
}


Here is the Unit Test that is executing the getNumberOfReviews method:

public class Grader {

@Grade(points=10)
@Test
public void testGetNumberOfReviews()
{
GameInfo gi=new GameInfo("SomeGame");
Assert.assertEquals(0,gi.getNumberOfReviews());
gi.addReview(new Review("cool",5));
Assert.assertEquals(1,gi.getNumberOfReviews());

gi.addReview(new Review("terrible",1));
Assert.assertEquals(2,gi.getNumberOfReviews());
}

@Grade(points=15)
@Test


My code compiles, but it is not passing my Unit Test. I will get 15 points if it passes and I'm not getting any points. Please point out what I'm doing wrong.

UPDATE

My code compiles, but my unit test still fails with the getNumberofReviews Method. Any help as to why?

Answer

The problem with your code is that you are using the length of the reviews array to determine the actual number of reviews, and this length is always 10 during your unit tests. Look closely at your code:

private Review[] reviews = new Review[10];

and then in your getNumberOfReviews() method you tally the count based on this length:

for (int i = 0; i < this.reviews.length; ++i) {
    ++count;
}

As a result, the apparent number of reviews always appears to be 10, and your unit test assertions fail.

If you insist on using a fixed size array to store reviews (which I don't prefer, I'd rather use an ArrayList), then you need to maintain some state, a counter, in your GameInfo class which keeps tracks of the actual number of reviews you have placed into the array:

class GameInfo {
    private int numReviews = 0;

    public void addReview(Review r) {
        this.reviews[numReviews++] = r;
    }

    // ...
}

Update:

If you wanted to use an ArrayList to store your reviews, the skeleton code would look something like this:

class GameInfo {
    private List<Review> reviews = new ArrayList<>();

    public void addReview(Review r) {
        reviews.add(r);
    }

    public int getNumberOfReviews() {
        return reviews.size();
    }
}

The advantage of using a Java collection here (in this case ArrayList) is many fold. First, it will grow automatically as you add reviews, and you don't need to worry about this. Also, if you need to get features, such as the size, this state is part of the collection, so you don't need to keep track of a separate count.

Comments