Chapter contributed by Brendan Barber
Student: I really want to work at Google one day, and I was thinking that the best way for me to get a job there would be to make my own version of Google. Have we covered enough to do that?
Prof: Well, Google, the search engine, is a very large and complex piece of software. Let’s start small and implement a small piece of it. Have you ever used Advanced Image Search on Google? It looks like this:
Student: Hmm, I didn’t know about this. So where would I start with making my own version?
Prof: Here, let’s use what we know about records and methods to start by making a query. We have to describe every image so that we can search specifically for the ones we want. So how about you start out with creating an
ImageData record that has a String with keywords and a String for the image file type. Then, create a boolean method for checking if a given file extension matches the record’s file type.Student: Ok, so by defining the keywords and file types of an image, I could now only search for PNG images.
Prof: Exactly. And you can also do the reverse: search for all image types except for PNG images. Now, based on the image from Google, and your own experience searching for images online, what do you think we should add to
ImageData?Student: Well, I don’t like when I find low-resolution images. So maybe I should add a width and height?
Prof: Great idea! Add it to the record and also try to make a new method similar to
matchesExtension but for width instead.Student: Wait a second, what does
this mean?Prof: When we use the
this keyword, we are referring to “the record that this method was called on.” So if you were to write i1.matchesExtension("png"), Java runs the method body with this standing for i1. So this.fileType refers to the fileType of i1.Student: Ok, I see. So I need to make sure to use
this in my hasWidth method.Student: Uhm, what did I do wrong. You taught me that I should be using
.equals(), like I did when writing the matchesExtension method.Prof: Not quite. Here’s what’s going on:
.equals(...) is a method call, and methods must be called on objects. A primitive value like an int does not have methods, which is what the compiler means by “primitive type” in that error message. For primitives, == already compares the numbers themselves.Student: So
.equals() cannot be used in this case, so I should go back to using ==.Student: Ok great, but I usually care about the width and the height of the image, and I am not looking for an image that is exactly a certain size.
Prof: Right, so how about you try writing a method that returns
true if the image is larger than a minimum width AND a minimum height.Student: Hmm, I only know how to check one thing at a time. I can use
if statements, one for the width and then inside another one for the height. Can I do that here?Prof: Try it and see.
Student: Nice, it works.
bigEnough is true, and the other two are false.Prof: It does work, and that’s a perfectly good way to write it out.
Student: Hmm, but the answer is
true when both checks pass, and the order of the width and the height check doesn’t really matter. That feels like it should be shorter.Prof: It can be. Try taking both of those checks and using
&& between them. Remember that the return just needs to be an expression that is true or false, it doesn’t necessarily have to be written out as return true.Student: So I can combine my two checks with
&& and return the result directly?Prof: It’s a good habit to notice when a few nested
if statements could instead be a single line with &&, imagine we had a 3D object and we had width, height, and depth. Then the nesting would be even worse!Prof: Ok, so let’s review what we have done so far. We wanted a way to search through images, so we defined
ImageData to have the fields we wanted to sort by and then we added true-or-false questions about the data with matchesExtension, hasWidth, and largerThan.Student: I don’t think Google is hiring me if this is all I show them, I mean right now all I can do is search by either size or by the file type. I guess I could combine them into one check, but I am gonna get bored if I have to write hundreds of methods in ImageData…
Prof: Hold that thought.
Practice
Fill in the blanks so largerThan is true only when both the width and the height are big enough, and so matchesExtension("jpg") is false for a PNG.
record ImageData(String keywords, String fileType, int width, int height) {
boolean matchesExtension(String ext) {
return this.fileType.equals(ext);
}
largerThan(int , int minHeight) {
this.width >= minWidth this.height >= ;
}
}
void main() {
ImageData i1 = new ImageData("cat sleeping", "png", 640, 480);
assertEquals(true, i1.matchesExtension("png"));
assertEquals(, );
System.out.println("All tests succeeded!");
}
boolean matchesExtension(String ext) {
return this.fileType.equals(ext);
}
largerThan(int , int minHeight) {
this.width >= minWidth this.height >= ;
}
}
void main() {
ImageData i1 = new ImageData("cat sleeping", "png", 640, 480);
assertEquals(true, i1.matchesExtension("png"));
assertEquals(, );
System.out.println("All tests succeeded!");
}