1. Playing with Objects is Still Fun
Worth: 5%
DUE: September 27, 11:55pm; submitted on MOODLE.
1.1. Task
The goal is to create a collection of Country
objects. The collection, called a CountryCatalogue
, will provide
functionality to store (add/remove) the Country
objects in addition to making inquiries about the data in the
collection.
Effectively, the idea is to recreate your assignment 4 written in Python from the previous course, but in Java. Be aware that the assignment is not identical and the requirements outlined here will be what is required.
You will
Create a
Country
class to store details about a countryCreate a
CountryCatalogue
classProvide a way to add and remove
Country
objectsSearch through the catalogue
Ask questions about the data in the catalogue
Filter data in the catalogue
Test the implementation with the provided test classes
Use the classes to build a
CountryCatalogue
Read data from a file
Write data to a file
1.2. Provided Files
You are provided with
A nearly empty Country.java file to be completed
A nearly empty CountryCatalogue.java file to be completed
A completed Asn1.java file with a
main
method and some testing codeA csv file called country_data.csv containing information about countries to be added to a
CountryCatalogue
A completed CountryTest.java file containing unit tests for the
Country
classA completed CountryCatalogueTest.java file containing unit tests for the
CountryCatalogue
classAll of this can be downloaded from here
This is a compressed IntelliJ project
Just unzip, put it where you want on your computer, and you should be able to open this project through IntelliJ
Warning
When opening the project, IntelliJ may mention a missing JDK. If this is the case, simply select the download link in the notification to download and install the missing JDK.
1.3. Part 0 — Read the Assignment
Read the assignment description in its entirety before starting.
1.4. Part 1 — Country
The Country
class will store data related to the country it represents. The data stored will be the country
name
, population
, area
, and continent
. The CountryCatalogue
class described in part 2 will store
instances of the Country
class.
Write a constructor for the
Country
class that takes four (4) parameters to be stored as class fieldsname
— typeString
continent
— typeString
population
– typelong
area
— typedouble
Note
Notice that the type for
population
is along
. One may be tempted to simply use anint
, but theint
type has a limitation.In Java,
int
values are stored in four bytes (4B)/32 bits (32b), which means the number of unique values theint
can represent is \(2^{32}\), which is \(4,294,967,296\). More specifically,int
values can store values between \(-2,147,483,648\) and \(+2,147,483,647\). Since the population of continents can exceed two billion, theint
is not going to work.The simplest solution to this problem is to make use of the
long
type.long
values are just likeint
values, but are stored in eight bytes (8B)/64 bits (64b). This means along
can represent \(2^{64}\) (\(1.84^{19}\)) unique values.Write accessor/getter methods for each class field
Call these methods
getX
whereX
is the name specific fieldFor example,
getArea
would return the fieldarea
Write a method to calculate and return the population density (
population/area
)Call this method
populationDensity
With floating point numbers (doubles included), division by zero results in a special value —
Infinity
If this method is called on a
Country
object with anarea
of zero, it should returnInfinity
In other words, this method should not perform any special check for
area
being zero
Write a
toString
method to return a string following the patternClassName(field=value, field=value, ... )
For example —
Country(name=Canada, continent=North America, population=34207000, area=9976140.00)
Mind the format of the string — the area field has two decimal places
Write an
equals
andhashCode
methodTwo
Country
objects will be considered equal if all fields match
Run the unit tests to ensure the
Country
class works properlyIt may be necessary to add JUnit to the class path, as described in the testing topic
Warning
Be sure to use JUnit 5. If you use JUnit 4, the tests will not work. Further, if you select JUnit 4 by accident, changing the project to use JUnit 5 can be difficult.
1.5. Part 2 — Country Catalogue
The CountryCatalogue
class holds references to Country
objects. Additionally, the CountryCatalogue
provides
functionality to add and remove Country
objects to itself and ask questions about the data. The CountryCatalogue
is effectively a list keeping track of the Country
objects with additional functionality.
Although the description of this class is provided with an order and each part is numbered, one should feel free to complete the methods in any order they see fit. Additionally, feel free to write and use additional private methods as needed.
The CountryCatalogue
class will need two fields
size
— anint
to keep track of the number ofCountry
objects in the catalogue
catalogue
— an array ofCountry
objects
The class will also have two static constants
An
int
calledNOT_FOUND
that is set to-1
This constant serves as a nice way to indicate, with a sentinel value, that something was not found
An
int
for this class calledDEFAULT_CAPACITY
that should be set to10
This will be used as a starting size for the
catalogue
array if none is specified upon creation
Write two constructors for the
CountryCatalogue
classOne creates the
CountryCatalogue
with thecatalogue
array being the default sizeOne takes a parameter to create a
CountryCatalogue
with thecatalogue
array being the size specified by the parameter
Write an
add
method to add aCountry
object to theCountryCatalogue
This method takes the
Country
object to be added as a parameterThis method returns a
boolean
indicating if the add was successfulThis method must still work if the
catalogue
array is full
Write a
remove
method that removes aCountry
object from theCountryCatalogue
This method takes the
Country
object to be removed as a parameterThis method returns a
boolean
indicating if the remove was successfulReturns
true
if the remove was successfulReturns
false
if the remove was unsuccessful; if the element to be removed does not exist
If more than one matching
Country
object exists, only remove the first occurrenceIf a
Country
object is removed, the order of the remainingCountry
objects must remain unchangedFor example, if
A
is removed fromC, A, R, L
, the result should beC, R, L
Write a
contains
method that searches for aCountry
object within theCountryCatalogue
This method takes the
Country
to search for as a parameterThis method returns a
boolean
indicating if the specifiedCountry
object is within theCountryCatalogue
Write an
indexOf
method that finds the index of aCountry
object within theCountryCatalogue
This method takes the
Country
to search for as a parameterThis method returns the index of the specified
Country
object within theCountryCatalogue
This method throws a
NoSuchElementException
if no matchingCountry
object exists
Write a
get
method that returns theCountry
object at a specified index within theCountryCatalogue
This method takes an index as a parameter
This method returns a reference to the
Country
object at the specified index in thecatalogue
arrayThis method throws a
IndexOutOfBoundsException
if an inadmissible index is provided
Write a
smallestPopulationDensity
method that returns theCountry
in theCountryCatalogue
with the smallest population densityThis method returns a reference to the
Country
object with the smallest population densityIf more than one
Country
object has the same smallest population density, return the first occurrenceThis method throws a
NoSuchElementException
if theCountryCatalogue
is empty
Write a
largestPopulationDensity
method that returns theCountry
in theCountryCatalogue
with the largest population densityThis method returns a reference to the
Country
object with the largest population densityIf more than one
Country
object has the same largest population density, return the first occurrenceThis method throws a
NoSuchElementException
if theCountryCatalogue
is empty
Write a
filterByPopulationDensity
method that returns a newCountryCatalogue
containingCountry
objects within the specified rangeThis method takes two parameters indicating the low and high limits for filtering
The lower limit is inclusive —
Country
objects with population densities greater than or equal to this limit are includedThe upper limit is exclusive —
Country
objects with population densities strictly less than this limit are included
This method returns a new
CountryCatalogue
containingCountry
objects from the currentCountryCatalogue
that fall within the specified rangeThis method returns an empty
CountryCatalogue
if noCountry
objects exist within the specified rangeThis includes the case that the current
CountryCatalogue
is empty
Write a
mostPopulousContinent
method that returns the name of the continent with the largest populationThis method returns a
String
of the name of the continent with the largest populationThis method throws a
NoSuchElementException
if theCountryCatalogue
is emptyThis method only considers
Country
objects contained within theCountryCatalogue
This method should work with an arbitrary number of possible continents
In other words, do not hard code the names of the continents on Earth
It is recommended to make use of a hash map for this method
A map is like a dictionary from Python
Write an
isEmpty
method that returns aboolean
indicating if theCountryCatalogue
is empty or notWrite a
size
method that returns the number ofCountry
objects within theCountryCatalogue
Write a
toString
method that returns aString
representation of theCountryCatalogue
The
String
should be an aggregate of theString
representations of theCountry
objects within theCountryCatalogue
Each
Country
object’sString
representation should be on its own lineFor example
Country(name=Nigeria, continent=Africa, population=186987563, area=912134.45) Country(name=Mexico, continent=North America, population=128632004, area=1969230.76) Country(name=Egypt, continent=Africa, population=93383574, area=1000000.00) Country(name=France, continent=Europe, population=64668129, area=541656.76) Country(name=Italy, continent=Europe, population=59801004, area=300000.00)
Uncomment out the provided
equals
andhashCode
methodsThese are provided since writing
equals
for collections and testing them can be tricky
Run the unit tests to ensure the
Country
class works properly
1.6. Part 3 — File IO and Using Classes
A complete main
method has been provided to you within the Asn1
class. Take your time to read over the code
carefully and make sense of what it is doing. You are not required to make any changes to this code, but you are
required to understand it and how it works.
The first portion of main
loads data from a file, parses it, and then uses the data to create Country
objects to
add to a CountryCatalogue
.
The next portion simply alters the contents of the CountryCatalogue
object and the third part queries the
CountryCatalogue
for some details.
The last portion of main
creates a new CountryCatalogue
by filtering the existing CountryCatalogue
. The
details of the Country
objects within the new filtered CountryCatalogue
are added to a string that is then
ultimately saved to a csv file.
There are no unit tests for main
. To test it, simply run it and check if it works as expected.
Note
In the Python implementation in the previous course, most file IO was done by reading/writing a single line at a time from/to the file. It is entirely possible to read/write one line at a time in Java, but here, when reading from a file, notice that the whole contents of the file is read as a single string and then parsed. Similarly, when writing to a file, the whole string is created before it is written to the file as a single string.
Note
The functions Files.readString
and Files.writeString
used for file IO may throw IOExceptions
. Notice,
however, that these calls are not wrapped with try
/catch
. This is because main
includes
throws IOException
in its signature, as described in the
Java vs. Python topic’s IO Section.
1.7. Part 4 — Testing
You might need to add JUnit to the classpath for the project, as described in the testing topic.
You may have already verified the correctness of your Country
and CountryCatalogue
classes by running their test
classes. If not, do it!
If you have, for good measure, re-run all the tests provided to you. If they all pass, you should be pretty confident that you have everything working correctly.
There are no tests provided for the Asn1
class, but that’s nothing to worry about. You can get a sense that it is
working correctly by running the main
method and checking that everything worked as expected.
1.8. Some Hints
Work on one method at a time
Get each method working perfectly before you go on to the next one
Test each method as you write it
This is a really nice thing about programming; you can call your methods and see what result gets returned
Mentally test before you even write — what does this method do? What problem is it solving?
If you need help, ask
Drop by office hours
1.9. Some Marking Details
Warning
Just because your program produces the correct output, that does not necessarily mean that you will get perfect, or even that your program is correct.
Below is a list of both quantitative and qualitative things we will look for:
Correctness?
Did you follow instructions?
Comments?
Variable Names?
Style?
Did you do just weird things that make no sense?
1.10. What to Submit to Moodle
Make sure your NAME, SCHOOL EMAIL, and STUDENT NUMBER appear in a comment at the top of the classes
Submit your completed .java files to Moodle
Country.java and CountryCatalogue.java
Do not submit the Asn1.java file
Do not submit the .csv files
Do not submit the .class files
Do not compress the files
Warning
Verify that your submission to Moodle worked. If you submit incorrectly, you will get a 0.