Jack Madden
Throughout this chapter, the main point is reading documentation of the library classes. A good programmer will learn to read the documentation, and understand it well.
The Java library is arranged in relationships. So items in the java.util.*
collection will all have a relationship, Like ArrayList
does as one class. Throughout this chapter, several new classes will be discussed. Such as
We will also have a look at writing our own documentation, for classes that we write ourselves.
Code is more secure, if it only has access to the data it needs to fulfil its function. There are Java mechanisms for this.
And we will also look at storing data and defining methods to be used on the class itself.
The Java Standard class library contains many classes. It is important to know how to use the library.
The Java library is extensive, it includes thousands of classes. It is impossible to try and remember them all, so a good programmer will
ArrayList
)During this section of the book, we will show you how to look up important classes from the library. The library is available in HTML format. We will also look at writing our own documentation for our own classes.
As always we shall explore these items with an example.
The TechSupport v1 system is three classes
The most interesting piece of the software is the method in the middle start
Which looks a little like this
boolean finished = false;
while(!finished) {
do something
if(exit condition) {
= true;
finished } else {
do something more
}
}
This is a classic while loop, with the initial finished flag set to false. The loop repeatedly
The last bit of the code reads the exit condition.
String input = reader.getInput();
if(input.startsWith("bye")) {
= true;
finished }
And the program will then decide if the user wants to exit or not? But the code can be improved in certain ways. If the user enters the word “Bye” or ” bye” then the program will fail to exit. But we can solve these problems, if we know more about the String
class.
The Java class library documentation shows details about all classes in the library. Using this documentation is essential in order to make good use of the library classes.
Choose java class libraries
from the Bluej help
menu. This will open up a new browser interface with three frames.
Documentation includes many pieces of information
The interface of a class describes what a class does and how it can be used without showing the implementation.
All this together is called the interface. Note that this does not show the class source code. This is abstraction.
The source code behind the scene is called the implementation.
The complete source code that defines a class is called the implementation of that class
The documentation of the String
class tells us that we need to call the trim
method. This will remove the white space around the string.
An object is said to be immutable if its contents or state cannot be changed once it has been created. Strings are an example of immutable objects.
String objects are immutable, please note that the trim method returns a new String. A common error is to put
.toUpperCase(); input
Where as the proper way is to use
= input.toUpperCase(); input
So the proper way to use trim is to
= input.trim(); input
So now we can build the proper way to ensure that the string is correct
String input = reader.getInput();
= input.trim().toLowerCase();
input if(input.startsWith("bye")) {
= true;
finished } else {
*code omitted*
}
We will add a Random
behavior to our responder
class. To do this, we will need an ArrayList
and pick one via our random number generator.
The Random
class is located in java.util.Random;
.
To generate a random number
import java.util.random;
public class GenerateRandom
{
private Random randomGenerator;
public GenerarateRandom()
{
= new Random();
randomGenerator }
public void generate()
{
System.out.println(randomGenerator.nextInt());
}
}
It is possible to generate numbers within a limited range. When getting random numbers, you must check whether the boundaries are inclusive or Exclusive.
The .nextInt
method of the random class is set to 0(inclusive) up to the next number of n-1(exclusive).
Now we can look at generating random responses.
The most interesting part of the generate response method
public String generateResponse()
{
int index = randomGenerator.nextInt(responses.size());
return responses.get(index);
}
The first line of the code does three things
The last line in the method does two things
The angle brackets <>
in ArrayList<E>
or HashMap<K, V>
or any other class, are known as parameterized classes or generic classes. This tells us that the class name is incomplete until we pass it a parameter.
Lets look at the top of the class at the import statements.
Class library’s are not available for use without an import statement. This is called importing the class and is done via the import statement. Because the library holds thousands of classes, Java uses packages to contain them. ArrayList
and Random
both belong in the package java.util
. The full name of a class is the name of the package, followed by a dot,followed by the class name.
The conditional operator is used to select one of two alternative values based on a boolean expression.
It looks like this
= age < 18 ? "child" : "adult"; ticketType
This is a ternary operator.
The switch statement uses three keywords: switch, case, (and optionally) default.
It looks like this
public void choice(response){
switch (response) {
case 0: myResponse = "Yes";
break;
case 1: myResponse = "No";
break;
default: myResponse = "Maybe";
break;
}
}
The default part deals with the cases that switch cannot answer.
For this we will use a HashMap
(dictionary) which is a specialization of Map
.
A
map
is a collection that stores key/value pairs as entries. Values can be looked up by providing the key.
A map is a collection of key/value pairs of objects. It is flexible with the number of entries it can take. A map entry is a pair of objects. This pair is a key and a value.
HashMap
The most important methods of a HashMap
are put
and get
.
The put method inserts an entry into the map. The get method retrieves that entry from the map.
It looks like this
HashMap<String, String> contacts = new HashMap<>();
.put("Jack Madden", "07777 777777");
contacts.put("Kirsty Madden", "07888 999000");
contactsString number = contacts.get("Jack Madden");
A set is a collection that stores each individual item at most once. It does maintain any specific order.
The Java library includes different versions of sets. The class we will look at is called a HashSet
.
HashSet
A HashSet
looks like this
HashSet<String> mySet = new HashSet<>();
.add("One");
mySet.add("Two");
mySet.add("Three);
mySetboolean x = mySet.contains("Two");
A set does not maintain any particular order. It ensures that the most you can enter into the set is once. Entering an item two or more times into the set does nothing.
By iterating over a set one by one, each object in the set can be accessed one at a time.
The Java method keySet
is used to return all of its keys. This will return a set
of keys
from the map.
The following code can be used to iterate over the map.
for (String aKey : myMap.keySet()) {
System.out.println(aKey);
}
This will print out the keys
one at a time.
We can use the String.split()
method to split the string.
That looks something like this
String[] wordArray= inputLine.split(" "); // Split at spaces
This will return an array of strings.
Wrapper classes provide a way to use primitive data types as reference data types. Reference data types contain useful methods that can be used with collections.
Autoboxing is performed automatically when a primitive-type value is used in a context requiring a wrapper type
All primitive types are noted in the books Appendix b Primitive types in Java must be wrapped up before any type of work can be carried out. This is done automatically with a process called autoboxing
As well as autoboxing there is unboxing which is also performed automatically. Unboxing does the opposite to autoboxing.
In this section we have a go with the getOrDefault
method of the HashMap
. The getOrDefault
method helps to avoid possible null
values returned from a map when using the default get
method.
A map with a set as a value looks like this
This goes at the top of the file
HashMap<String, HashSet<String>> animalMap;
This goes in the constructor
= new HashMap<>(); animalMap
And these go elsewhere
.put("Reptiles", new HashSet<>());
animalMap.put("Chelonians", new HashSet<>());
animalMap.put("Mammals", new HashSet<>()); animalMap
It is important to write documentation for your clases as you develop them.
The documentation of a class should be detailed enough for other programmers to use the class without the need to read the implementation.
When using a class from the library such as HashMap
we relied upon the documentation to find out how to use them. This is true for our own classes.
Java systems use a tool called javadoc.
The document of the class should hopefully include
The documentation of a constructor/method should include
Each project will also have a ReadMe file. This is where you will write your overall project comment.
The tags are called “annotations”
The javadoc comments look like this
/**
This is a javadoc comment*/
In Java we use an “@” symbol to highlight bits of the documentation. These include, but are not limited to
Public or Private are the Access modifiers at the beginning of field/method declarations. If a method is public it can be invoked from the same class or any other class. If a method is private it can only be used by the same class.
Access modifiers define the visibility of a field, constructor or method. Public elements are accessible from inside the same class or other classes. Private elements are only accessible from within the same class.
There are times when we need to use private methods/constructors. These are called Helper methods.
In many programming languages the internals of a class (implementation) are hidden from the user. The object has become a ‘black box’ with its data only being accessible through a limited set of public methods. There are two aspects to this
Not needing to know - is about abstraction and modularization. Not allowed to know - is about modularization in a different way. This ensures that one class does not depend on another.
Information Hiding is a principle that states that internal details of a classes implementation should be hidden from other classes. It ensures better modularization of an application.
This is very important for maintenance work and fixing bugs. This issue is known as coupling. Weak coupling is a good thing. If it was up to the maintainer to change change the ArrayList
you will not have to make changes to any of your code because you have not made any references to the implementation of ArrayList
in your file.
The programming of both classes (even if there both you) should be loosely coupled.
Java has four different access modifiers
Typing CTRL-space will bring up a pop-up menu of all methods we have available. Hitting return enters the method into our source code.
We will look at the keywords static and final.
The keyword static defines a class variable. These are stored in the class itself, not an object.
Classes can have fields. These are known as Class variables or Static variables. Exactly one copy of a class variable exists at all times, independent of the number of created instances.
Static variables are written in all caps to let the user know what they are. They look like this
public class BouncingBall
{
// Effect of gravity
private static final int GRAVITY = 3;
private int xPosition;
private int yPosition;
}
Static variables can be accessed by any instance of the class. The objects share this variable.
Constants are defined with the keyword final. For example
private final int SIZE = 10;
The look the same as a field declaration but
Constants are written in all caps. Constants are frequently used with all instances of a class. They are called class constants.
Just as static variables belong to a class, so do static methods. They look like this
public static int getNumberOfDaysThisMonth()
{
...
}
Note the static keyword in the methods header. So if this was a method in Calender, it would be called like this
int days = Calender.getNumberOfDaysThisMonth();
Note that Calendar is used, not the instance of the class.
There are two limitations with class methods
We will need a main method to do this
Firstly the user must specify a class to launch the program. The Java system will look for a method called main This looks like
public static void main(String args[])
Please see Appendix E of the book.
Now we will look at some more advanced material
In object-oriented programming, relationships between classes are expressed via inheritance. So a
List<Track> tracks = new LinkedList<>();
Is said to be of type List
, even though the object stored in it is of type LinkedList
. These are called polymorphic variables.
So a call to add, get, clear, remove or size on tracks would all have the same syntax. The point of polymorphic variables is that if we ever needed to change type, the only place in the code we would have to change would be the place where the object is created.
The collect method is a terminal operation. So we will use it as a final operation on a stream.
There are two collect methods, but here we will be talking about the simplest. The collect method takes a collector. This is something that can accumulate elements of its input stream.
The easiest way to use a collector, is to use one of the static methods available in the collectors class. This can be either toList
, toMap
or toSet
.
So for example
public List<Sighting> getSighting(String animal)
{
return sightings.stream()
.filter(record -> animal.equals(record.getAnimal()))
.collect(Collectors.toList());
}
If we want to collect the object into a particular type of collection, we must do this differently.
This is how we do it
public List<Sighting> getSightingOf(String animal)
{
return sightings.stream()
.filter(record -> animal.equals(record.getAnimal()))
.collect(Collectors.toCollection(ArrayList::new));
}
This parameter uses a notation which is called a method reference. A method reference uses a new style of syntax, ::
double colons.
There are four cases of method references
() -> new ArrayList<>()
System.out::println
Math::abs
String::length