The Review Analysis FRQ from the 2022 AP Computer Science exam has you working with an ArrayList
of Review
class references. You’ll often see a question like this where you’re working with an array or ArrayList
of some arbitrary class that you’ve never seen before.
In this case, a Review
contains information about the rating and optional comment left by a user on a website. There’s not too much to the Review
class, but you will need to know which methods it contains to be able to answer the questions.
public class Review {
private int rating;
private String comment;
public Review (int r, String c) {
rating = r;
comment = c;
}
public int getRating() { return rating; }
public String getComment() { return comment; }
}
If you haven’t already, it’s worth taking a look at the full PDF from College Board. It goes into a bit more detail on the Review
class and much more detail on the ReviewAnalysis
class we’re going to look at in next.
public class ReviewAnalysis {
private Review[] allReviews;
public ReviewAnalysis() {
// Implementation not shown
}
public double getAverageRating() {
// Part A
}
public ArrayList<String> collectComments() {
// Part B
}
}
Your first task is to go through all the Review
references in the array allReviews
and calculate an average. Hopefully you’ve done enough labs that finding the average was relatively easy.
There are two catches to this though that some students would have missed.
First, it’s an array of references, so you can’t just use +=
on literal numbers. You have to have seen that each Review
has a getRating()
method to give you access to the rating
instance variable. You can’t use rating
, you have to use getRating()
.
And two, you’re going to be averaging int
values, but returning a double
. You need to be careful and remember how Java handles int
division.
public double getAverageRating() {
int sum = 0;
for (int i=0; i<allReviews.length; i++) {
sum += allReviews[i].getRating();
}
return (double)sum / allReviews.length;
}
Notice on the return that I cast sum
to a double
before dividing it out. That gets us the right value. An int
divided by an int
is an int
in Java, and any decimals are truncated. But if either value, or both, is a double
it calculates the result as a double
And let’s look at a slightly different version. This time sum
is going to be defined as a double
so we don’t need to worry about casting it later. And, we’re going to use a for each loop instead.
public double getAverageRating() {
double sum = 0.0;
for (Review r: allReviews){
sum += r.getRating();
}
return sum / allReviews.length;
}
For Part B we’re filling and returning an ArrayList<String>
with comments that contain an exclamation point, but only after doing a bit of formatting.
If the comment contains an exclamation point, we’re then going to
public ArrayList<String> collectComments() {
ArrayList<String> comments = new ArrayList<>();
for (int i=0; i<allReviews.length; i++) {
String c = allReviews[i].getComment();
if (c.indexOf("!") >= 0) {
String end = c.substring(c.length() - 1);
if (!end.equals(".") && !end.equals("!")) {
c += ".";
}
comments.add(i + "-" + c);
}
}
return comments;
}
Let’s step through what we did here.
ArrayList
, comments
to hold the comments we want to keep.allComments
. Used a for loop here instead of a for each because we needed the index value as part of the formatted string we’re going to be adding to comments
.allReviews[i]
in a throw away variable c
so that I didn’t have to keep typing allReviews[i]
c
. If there’s not, we don’t have to do anything with the comment.s.substring(c.length() - 1)
in end
to shorten up the next line a bit. end
is the last character in c
.end
isn’t an exclamation point or a period then a period gets concatenated onto the end of c
.i + "-" + c
is then concatenated together and added to comments
comments
is returned at the end.