This might not be complete or thorough enough... Always seek knowledge from textbooks! They tend to be quite complete... (I hope you have one available!)
Where I want everybody to be after demonstration 6:
You are familiar with the key concepts introduced in demonstrations 1 through 6.
You are now fully comfortable with making your own experiments with Java programs: You know how to make small changes to your code, at the same time keeping your code well-structured and correctly indented with respect to code conventions. You know not to make too big changes before re-compiling and trying to execute your program. You know that this is a good way of doing programs:
- First think about what you want to achieve
- Then make a proper set of test cases
- Modify your code, one very small step at a time, towards the goal. Make experiments, and time to time refactor the code, i.e., make it follow conventions, document it, make all the names understandable, shorten the code, make it resemble the actual meaning that emerges in your head.
- When the code doesn't seem to "emerge in your head", go think about the algorithm without programming: try to "be the algorithm" by yourself: draw the desired results on paper for some small test cases; think and play with your hands, legs and real-world analogies. Try to find out what exactly you are doing with the pen and paper (or a phone directory, or a deck of playing cards, or dice, or water faucets, ...) when you are solving a problem similar to your programming problem, producing output from input. This is probably exactly the thing you want to write in a programming language! The rest is just translation of the idea to a programming language syntax. And considering the way in which data needs to be encoded in a computer.
Agenda for the next step:
First of all we complete our tool set:
We take the Eclipse IDE as our tool from now on. We will not forget about text editors and command line tools, but we will add a bit of "convenience" and "luxury" on top of them. Thereby speeding up the process of making programs very much!
This is where you can download Eclipse for your home computer:
You may need to make some additional setups to make it work. We might need to Google up some solutions. Try it out, and see if there are problems.
Some basic setups will need to be done in your Workspace:
- Project->Properties->Java Compiler, then "Configure Workspace settings", and set "Compiler compliance level:" to at least 5.
- Project->Properties->Java Code Style->Formatter, then "Configure Workspace settings", and "Select a profile"->"Java conventions [built-in]". Then "Edit"->"General settings"->"Tab Policy:" set to "Spaces only". Then click on Apply, and save the profile with a new name, let us say "Java conventions for Programming 1".
NOTE 1: The compilation and execution steps are still happening all the time, but with the IDE (Integrated Development Environment) they happen automatically.
NOTE 2: The file system still contains all the programs as source code files (compilation units) within a directory hierarchy, although the view is now a graphical "tree view" where you can just point-and-click with the mouse.
NOTE 3: You must understand, and be able to use the code conventions at all times, although the IDE will provide them automatically whenever you click Source->Format.
NOTE 4: The debugger with breakpoints and step execution is a powerful tool which must be learned as soon as possible. We'll look at examples on the Friday lectures.
Then, if we have time, we go a bit into Object Orientated Programming (OOP) and thinking. Not fully, but preliminarily:
Let us seek some knowledge about objects (instances), classes, "identity" of an object, and reference variables.
The small difference between static and non-static methods should be considered.
Let us start using some objects of classes provided by the Java platform: Good classes in the beginning are String and StringBuilder for manipulating character strings. Other necessary "first classes" include all kinds of array types, which in Java are seen as objects.
We could also look at further control structures. Let's continue with continue and break, and applying return in different places. And also something that I call "labelled statements" (not sure about the correct word).
Later we add at least switch, try-catch-finally, throw. (And after those, we have seen about all of the statements that you can ever write in Java).
Contents
Last time I mentioned that there are only eight kinds of primitive types. All data structures in Java boil down to objects that contain these types of numerically coded values that represent integers, real (floating point) numbers, truth values, and Unicode characters.
But we have already seen that more flexible data types do exist; at least we have seen strings of characters, and printed them out -- starting from the very first Hello World! application. Actually we are dealing with data structures that are compounded from the primitive types by using "data abstraction mechanisms" provided by the programming tool of choice. In the case of Java, the abstraction mechanism is object-orientation.
What is an object? Philosophically it is "a thing that you can think of". For example, philosophically 'the weather' is an object, you are an object, and also all your friends and their houses and bikes and home countries are objects. A shimmering, blue, bitter smelling but sweet jelly cake is an object... You can think of these things.
What properties does an object have? Important things to notice:
- An object is an individual. Whatever you describe as an object, is exactly one thing that exists. You can say "my apartment" when you mean one particular place. You can say "student apartments all over Finland" when you mean one collection of places. You think about an object (the collection) that contains several other objects.
- Objects have an "address". We can call this a reference. Think about your cell phone. (You can think about it, so it is an object...) Anybody who has another phone and your phone number, can call you. Usually you see the caller's number on your cell phone when it rings. Let us say that the phone number is a reference that can be used to communicate to your phone. Clearly a phone number is unique -- a reference to an object is, since the object is unique. But there can be many copies of the number, each referring to the same object.
- Objects naturally are compounded of many objects. As the cell phone is attached to your ear and mouth, and ultimately to your mind, philosophically you are a network of connected objects -- a system which facilitates "Having a telephone conversation". The system itself can be considered an object, although it actually contains many smaller ones within itself. A telephone conversation cannot happen without the phone; you need a number of specific, interconnected objects in order to make systems function properly. The objects need to be of a proper type, and properly interconnected, in order to make something work. (For most purposes, you don't need an elephant to make a phone call, but to make a circus act, an elephant might be required.)
- An object has to exist in order to do anything purposeful. If one doesn't exist, you need to create a new object, or ask help from a factory that will create it for you.
- Objects can be classified, that is, of any object you can say which class it belongs to.
- The class defines what attributes, properties and capabilities belong to an object that belongs to the class.
Some examples of classes in "real life":
- Paavo, Chris and Kanako are persons.
- Your seat in a lecture hall is clearly an instance of a Seat.
- Classification is usually hierarchical: Object of type Seat is more generally an object of type Furniture.
What actually matters in classification is the interface of an object that belongs to a class. By interface, we simply mean the possible ways of interaction with an object. Each class of objects has its own interface. And it is less restricting to talk about interfaces rather than only classes because quite different classes can have the same interface. Think about my previous example where all tables and all seats and also desktop computers and even the head of a careful lecturer provided the interface that allows one to place a thing on top of the other object. It was immediately found out that this interface was not found in any of the wall objects.
In object oriented computing, using Java as an example:
- an object is a model that represents any philosophical object that is interesting in an application. For example, a banking software might deal with users and bank accounts. Each user would be represented by an object of class User. A bank account would be represented by an object of class Account. Users and accounts would be interconnected, and there would be plenty of objects of other classes such as Transaction, InterestRate, BankOffice, ATM...
- each object belongs to a class which needs to be defined.
- each class implements a set of interfaces.
Objects of class Qurzw have the following interface: You can create a Qurzw that is of a certain color (pink by default). You can warm up the Qurzw, and you can query it's current temperature. It is not possible to cool down a Qurzw, and when it overheats it becomes black forever. This is what a Qurzw is like. I can think about such a thing, so it is apparently a class of objects. I can make a model for such a Qurzw in Java:
public class Qurzw{ private String color; private double temperature; public Qurzw(){ color = "Pink"; setTemperature(21.0); } public Qurzw(String color){ this.color = color; setTemperature(21.0); } public Qurzw(String color, double temperature){ this.color = color; setTemperature(temperature); } public double getTemperature(){ return temperature; } public String getColor(){ return color; } private void setTemperature(double newTemp){ temperature = newTemp; if (newTemp>100) color = "Black"; } public void warmUp(){ setTemperature(getTemperature()+1.0); } public void warmUp(double howMuch){ setTemperature(getTemperature()+howMuch); } }
This is what object oriented programming is about: It is modelling the world using classes as an abstraction mechanism. So... I have defined a model, a class of objects of type Qurzw, and placed the model into a Java compilation unit. Try to examine the class definition. Then, try to make a program that creates a couple of Qurzws, warms them up, and prints out their colors. It could be in a different compilation unit, like TestQurzws.java. Something like the following:
public class TestQurzws{ public static void main(String[] args){ Qurzw cuteQurzw = new Qurzw(); Qurzw coolone = new Qurzw("Orange"); Qurzw hot = new Qurzw("Magenta", 90); System.out.printf("Overall temperature of the qurzws is %g degrees%n", cuteQurzw.getTemperature() + coolone.getTemperature() + hot.getTemperature()); System.out.println("What color is the qurzw: " + hot.getColor()); hot.warmUp(20); System.out.println("What color is the qurzw now: " + hot.getColor()); } }
It will be very instructive to run this program, and some variations, using the step debugger! You'll see how the execution flow goes in and out of the methods of Qurzw, and how the internal state of each individual changes as the method calls are performed.
Eventually you'll have to be able to read the Java platform API documentation, so you could as well have a look into some of the documentations already:
- here is documentation for the class String: http://java.sun.com/javase/6/docs/api/java/lang/String.html
- and here is the full Java SE API documentation: http://java.sun.com/javase/6/docs/api/
The class java.lang.String is a very fundamental one because objects belonging to it represent character strings. Each string literal that you might write in your applications, like "Hello world!" in the first one, become objects of class String. When you use such a literal, you are using a reference to an object of class String.
Try out some operations that seem to be possible with the basic strings:
String hello = "Hello"; String world = "World"; String hw = hello; hw += " "; // The operator '+' for Strings is a small // "quirk" in Java; maybe // more about this later... hw += world; hw = hw + hello + "!"; System.out.println(hw); // Try out some method calls for the object: int slength = hw.length(); System.out.printf("Length of my string is %d%n", slength); System.out.printf("The first character is %c and the last one %c%n", hw.charAt(0), hw.charAt(slength-1)); // Do you think this is possible: char c = hw.charAt(slength);
Exercise 2: String
Then make a subroutine that iterates through a String object, and finds out how many times a certain character is present in the string. Usage would be like the following:
char ch = 'k'; String st = "Kan we think of trinking some koffee, Khaled?"; System.out.printf("My string has %d occurrences of the letter %c", countChars(st, ch)); // I expect my subroutine to return the integer 3 for the above case // since 'k' and 'K' are different characters...
Exercise 3: StringBuilder
An object of the class String can never change form since it is created. We say it is an immutable class. It is a good thing that can be trusted. But when you need a mutable character string, for example, for changing one character to another character, you need to use the class java.lang.StringBuilder. Documentation is there: http://java.sun.com/javase/6/docs/api/java/lang/StringBuilder.html
Examples of use:
// A canonical way of creating any kind of object with the default // state (which, for StringBuilder, is an empty character string): StringBuilder myBuilder = new StringBuilder(); myBuilder.append("Hello"); // You can append a String System.out.println(myBuilder.toString()); // You can convert to String. myBuilder.append(' '); // You can append a char myBuilder.append(2); // You can append an integer System.out.println(myBuilder.toString()); myBuilder.append(" Worlds!"); String resultingText = myBuilder.toString(); // You can convert to String. System.out.println(resultingText); myBuilder.setCharAt(0, 'Y'); myBuilder.insert(5, 'w'); System.out.println("New one: " + myBuilder.toString()); System.out.println("Old one: " + resultingText); myBuilder.delete(6, 8); System.out.println("New one: " + myBuilder.toString()); System.out.println("Old one: " + resultingText); // This is how you manipulate objects: you call public instance // methods of the class, and you tell the method a reference to an // object individual on which it should operate. There's no // difference to the way of use, no matter what the object is.
Your assignment:
Make a subroutine that takes a StringBuilder reference as a parameter, and manipulates the string so that after return from the subroutine, occurences of a certain character have been replaced by another character. Of course, the subroutine takes as additional parameters the character that has to be replaced, and the character that will replace the other one. You need to iterate over all the characters using a loop structure, and handle the characters differently according to some condition. Have fun creating a replaceChars(stringb, oldChar, newChar) or the like!
A primitive type like an integer or a double precision floating point variable is useful, of course, but many times one value is just not enough. You need arrays of values instead. An array is an indexed set of values of a certain type.
Exercise 4: int[]
This is how you declare and create an array of integers in Java:
int[] myArr = {1,2,3,4,5}; // Arrays can be initialized with values. int[] myOtherArr; // But they don't have to be... myOtherArr = myArr; // Arrays are objects! Now we have two // references to the same object individual! // (print out values:) System.out.println("One array:"); for (int value: myArr) System.out.printf("%d ", value); System.out.printf("%nOther array:%n"); for (int value: myOtherArr) System.out.printf("%d ", value); System.out.println(); myArr[2] = -7890; // This is how you get to an indexed value System.out.println("One array:"); for (int value: myArr) System.out.printf("%d ", value); System.out.printf("%nOther array (or is it the same one??!):%n"); for (int value: myOtherArr) System.out.printf("%d ", value); System.out.println(); myOtherArr = new int[6]; // This is how you can create a new // array of some size, without initializing values // IF I remember correctly, the Java machine // guarantees initialization to zeros; but beware // the programming language that you use; might // as well be random contents! System.out.println("One array:"); for (int value: myArr) System.out.printf("%d ", value); System.out.printf("%nOther array (is it still the same?):%n"); for (int value: myOtherArr) System.out.printf("%d ", value); System.out.println();
Your assignment:
Make a subroutine that returns a new integer array that is filled with a range of numbers from an endpoint to another. Usage could be like the following:
int[] range = makeIntRange(-3, 2); // I want to see the numbers -3, -2, -1, 0, 1, 2 after the print: for (int value: range) System.out.printf("%d ", value);
Exercise 5: double[]
The array elements can be of any type (i.e., any of the primitive types, or references to any kind of objects) as long as all the elements in the array are of the exact same type. So we continue with real numbers instead of integers... Make a subroutine that creates and returns a new array of double values. The values have to be equidistant points on the real axis. Example of use:
double[] points = makeDoubleRange(1.0, 2.0, 11); // I want to see the 11 equidistant numbers from 1.0 to 2.0 from the // following printout. I.e., 1.0, 1.1, 1.2, ... 1.9, 2.0 for (double value: points) System.out.println(value);
Exercise 6: Command line arguments as an array of String-type references
Recap: The array elements can be of any type. Now we are ready to understand what it means to write the String[] args in public static void main(String[] args).
Try out the following program:
public class PrintArgs{ public static void main(String[] args){ for(int i=0; i<args.length; i++){ String jono = args[i]; System.out.printf("Argument %d is: %s%n", i, jono); System.out.printf("It's length is %d chars.%n", jono.length()); System.out.println("First char is " + jono.charAt(0)); System.out.println("Last char is " + jono.charAt(jono.length() - 1)); System.out.println("In upper case letters it's " + jono.toUpperCase()); System.out.println(); } } }
The code won't do much unless you run it from the command line, and give some additional arguments to the launch command. So try it in the Command Prompt like this:
javac PrintArgs.java java PrintArgs Hello, you "nice programme"
Try to figure out the program completely. Then try to produce a program that works as follows, from the command line. You'll need a couple of if-statements there to take the special cases into account:
javac ArgsParser.java java ArgsParser You have to give an argument! java ArgsParser what parameter You have to give exactly one argument! java ArgsParser ok Hello, ok! java ArgsParser what Hello, what! java ArgsParser Nieminen Hello, Nieminen! java ArgsParser Paavo How's the course progressing? java ArgsParser fine. Hello, fine.!