Showing posts with label basics. Show all posts
Showing posts with label basics. Show all posts

Saturday, June 11, 2016

Basics: Just what IS an object, anyway?

This is a pretty long one by the standards of this blog.  Try to stay with it, though, the concepts are crucial.

Whether people are experienced developers used to procedural languages or newcomers to programming in general, really understanding objects tends to be a bit of a sticking point.  It's odd, because once you start to get it, everything seems quite natural.

An object is a representation of...  something.  Sometimes they represent fairly nebulous concepts, sometimes they represent very real physical things, but in all cases they're a kind of model.  Objects have properties, just like a flower has a color or a bee has [6] legs.  Objects have methods, which are really just things you can ask them to do, like 'release pollen' or 'sting someone'.  Finally, objects have events, or at least they can generate events.  That could be 'I've been pollinated' or 'I left my stinger in someone'.  Any particular object may make use of one, two or all three of these constructs.

Objects are based on classes in Java.  There is an all too human tendency to use the terms interchangeably and I've probably been guilty of doing that, too.  Technically, a class defines how an object should be built and an object is an instance of such a class.  Basically, after you write your code you compile it to create a .class file, and then when you run your code you can make a new object from said class. Making objects is easy enough, most of them get created (or instantiated) by using the new keyword like this:

    SimpleObject myObject = new SimpleObject();

Let's break that down:

First, we have declared that we're interested in working with a variable of type SimpleObject.  In other words, someone out there has written a SimpleObject.java file that defined a SimpleObject class and you're going to make an object from that definition.

That variable will be called 'myObject'.  We have to name our variables or we'd have a really hard time referring to them in our code!

We're not referring to a previously existing SimpleObject, we're going to make a completely new one.  The actual creation is handled by a constructor inside of SimpleObject.java, and we need to rely on that constructor doing its job, correctly setting up anything within the new object that needs to be in place.

Some objects don't appear to have constructors at all if you read the code, but that just means that there is no need for a constructor to do any setup work, so the programmer was able to rely on Java creating a default constructor for them.  The code for SimpleObject may have been written either way.  We don't care at this point, we just know we can call it.  I'll get back to constructors a little later when we talk about actually writing a class of your own.

Defining an class in Java is straightforward enough.  You don't really have to do any more than create a .java file with a bit of correct syntax.  The following example is enough to make a SimpleObject class (which really can't do anything but exist):

package com.oopuniversity.simpleobject;

public class SimpleObject {
}

Of course, a class that doesn't do anything isn't very useful, but I think it's good to have a picture in your head of all the 'extra' stuff that absolutely needs to be in place.  Code can look a bit busy to new developers, and its best to know what is basically template stuff that you should make sure is there and then ignore.

Just to break it down, that 'package' statement up at the top tells the compiler where the generated class file should go.  It's basically specifying an output directory, but using periods instead of slashes or backslashes.   Packaging is primarily an organizational tool and it turns out to be an important one later on.

Then we have 'public class SimpleObject' which tells us we're defining a class called SimpleObject.  That public keyword is important, it controls whether other objects in a larger program are able to create SimpleObjects or even refer to them at all.  For now, just use 'public'.  The day will come when you start to use other modifiers for specific reasons, but if you're reading this to learn you don't have those reasons yet.

Then we have some curly braces.  Those are ubiquitous in Java programs, and basically set boundaries for chunks of code.  In this case, they are setting the boundary for the beginning and end of the class, although they don't actually contain anything.  Anything between those brackets will be considered an attempt at having something be a part of SimpleObject.

Man, four paragraphs to describe three lines...  I guess a fair amount of information is consolidated down into even that useless bit of code!  Fortunately, that stuff always stays pretty much the same.  Once you understand that structure, you can kind of stop worrying about it and move on.

I mentioned above that I would talk about constructors.  Well, that time has come.  The following code is (aside from being in a different package) precisely identical to the previous code:

package com.oopuniversity.simpleobjectwithconstructor;

public class SimpleObject {
    public SimpleObject() {
    }
}

The only differences are:

  1. We changed the package definition, which lets us have this version of SimpleObject sit in the same project as the previous version without any conflicts.
  2. Now we have something new inside the braces that define the class.

The package definition is needed because I'm keeping everything inside one big project.  Just like you can't have two files with the same name in one directory, you can't have two classes with the same name in one package.

The new stuff inside the braces is defining a default constructor for SimpleObject.  It's public which means other objects can use it to make a new SimpleObject.  It has nothing between the parentheses, which means you can create a SimpleObject without having to give it any parameters, which are nothing more than pieces of information you give it (we'll talk about those soon).  Then it has some more of those fun curly braces, which again define boundaries.  Anything inside this particular pair of braces belongs not just to the class, but to the constructor itself.

Why would you want to write a constructor like this, making your class busier?  Well, you wouldn't, and that's why you get this for free with any class you write that doesn't bother defining a constructor of its own.  However, you DO need to know about and understand this for one simple reason:  It is also possible to define a class using a constructor (or a whole bunch of them if you like) that has parameters.  If you do this, the compiler will *not* create a default constructor for you and you won't be able to use a default constructor unless you explicitly write one.

https://github.com/OOPUniversity/OOP_Basics

Friday, June 3, 2016

Super basic object stuff

I am not going to rework this right now, I think it gets the main points across as is.

From a recent Reddit post:

What you are asking about is quite basic to object oriented programming. Let's start with the first point I'd like to make: PersonA and PersonB are exactly the same thing, except the data is different. However, they cannot be simple methods that return integer values, that will never fly. The values you're setting up are lost as soon as the methods end.
Instead, you want to create objects of type Person. You do this by creating a class called Person and setting up variables to represent the values you want. At its absolute most basic (and this isn't correct, it's just showing the idea) it would look like this:
public class Person {
    public int x;
    public int y;
    public int range;
}
This is more akin to what we used to call a struct in c. Ordinarily you'd have a lot more stuff in there, but adding that right now could inhibit understanding so I want to take this slowly.
With the above class you could do this in the class you've posted:
public static void main(String [] args) {
    Person a = new Person();
    a.x = 200;
    a.y = 100;
    a.range = 160;

    Person b = new Person();       
    b.x = 100;
    b.y = 400;
    b.range = 170;
After that, you could use 'a.x' or 'b.range' the same way you were originally trying to use 'xA' or 'rangeB'.
Remember when I said that I was just showing the basics? Well, objects are a lot more powerful than just bags of variables. Let's use just another couple of features.
First, let's make a 'constructor' for Person so you can slim down your code:
public class Person {
    ... //What you already have
    public Person(int newX, int newY, int newRange) {
        x = newX;
        y = newY;
        range = newRange;
    }
}
Now your main can do this:
Person a = new Person(200, 100, 160);
Isn't that nicer?
Next, let's add 'accessor' methods to Person. Accessors are also called 'getters' and there are good reasons to use them. Trust me on this, I'm on the train and don't have time to fully explain:
public class Person {
    ... //What you already have

    public int getX() {
        return x;
    }

    //Do the same thing for 'y' and 'range'
}
At this point, you could still do 'a.x = 5' or 'range = b.range'. We can prevent that by marking the variables as 'private'
public class Person {
    private int x;
    private int y;
    private int range;
    ... //what you otherwise already have
}
But wait! Now when I try to write a.x=5 I get some horrible error and everything is broken and the world is ending!
No, you just need 'setters', also known as modifiers to do the job for you:
public class Person {
    ... //Everything you already have
    public void setX(int newX) {
        x = newX;
    }
    // Follow the same pattern for y and range
}
Now the equivalent to 'int range = a.range' is 'int range = a.getRange()', and the equivalent of 'a.range = 50' is 'a.setRange(50)'.
There's a LOT more to OOP, we've really just scratched the surface. But just encapsulating your data in this way will go a long way towards making your programs more readable, maintainable and robust.
I have no doubt that questions are coming up in your mind. I tried to make this clear and left out a few niceties in the interest of getting it written quickly and not overloading you, but it's a lot to absorb. Please ask questions when you need clarification.

Sunday, November 15, 2015

There's a loop for each of us

This is one of the really useful additions to the Java language specifications.  It greatly simplifies many loop structures, eliminating a bunch of verbiage that we long thought was just part of the deal when writing code.

Let's meet what I hope will become a good friend of yours:  The enhanced for, also known as the 'for each' loop.

The for each loop structure is an enhancement that can be used to replace many of the standard for or while loops you would otherwise be writing.  It is extremely common to have to, for instance, go over the elements of an array or a collection, extract one element at a time, and perform operations on it.  Let's pretend that we have an ArrayList of Person objects, and we want to print a list of first and last names.

In the old days we might have written this (and if you don't understand why I use 'List' instead of 'ArrayList' see 'Good Practices: Coding to the Interface'):

public static void printPersonList1(List personList) {
    System.out.println("Using a 'while' loop the JDK 1.4 (and earlier) way:");
    Iterator iter = personList.iterator();
    while(iter.hasNext()) {
        Person p = (Person) iter.next();
        System.out.println(p.getFirstName() + " " + p.getLastName());
    }
}

Now, one improvement was the addition of 'Generics', which allowed us to simplify the code a bit by informing the compiler that our List and Iterator had to be of type Person:

public static void printPersonList2(List personList) {
    System.out.println("Using a 'while' loop with generics:");
    Iterator <Person> iter = personList.iterator();
    while(iter.hasNext()) {
        Person p = iter.next();
        System.out.println(p.getFirstName() + " " + p.getLastName());
    }
}

Now, you might be wondering why I did my demonstrations of old style code with while loops to demonstrate a better for loop.  This is mostly because the while loop syntax is better suited to running over an Iterator than an old style for loop was.  It could be done, but frankly it's not as clean.  You'll note I had to leave out the third term of the for loop because it only gets executed after the body of the loop is complete and I had to pre-seed with the first value:

public static void printPersonList3(List<Person> personList) {
    System.out.println("Using a 'for' loop with generics:");
    Person p = null;
    for(Iterator <Person> iter = personList.iterator(); iter.hasNext(); ) {
        p = iter.next();
        System.out.println(p.getFirstName() + " " + p.getLastName());
    }
}


Alternately, we could have skipped the Iterator altogether, which is really more in keeping with the natural usage of the old style for loop:

public static void printPersonList4(List<Person> personList) {
    System.out.println("Using a 'for' loop with no iterator:");
    Person p = null;
    for(int i = 0; i < personList.size(); i++) {
        p = personList.get(i);
        System.out.println(p.getFirstName() + " " + p.getLastName());
    }
}


OK, here's the actual example I'm trying to get across to you.  This is the 'enhanced for' loop, also knows as the 'for each':

But the for each loop construct went a lot further and made things much better:

public static void printPersonList5(List<Person> personList) {
    System.out.println("Using a 'for each' loop:");
    for(Person p:personList) {
        System.out.println(p.getFirstName() + " " + p.getLastName());
    }
}

Note how concise it is, with no extra stuff.  Get Person objects from this collection and run with it.  Using the enhanced for loop simplifies our code, letting us get on with the conceptual task at hand and saving our fingers from some typing.  It's extremely common to go over a collection of data and perform some task on every element, so why should we have to write it all out explicitly every time?  You can use for each loops on classes based on Collection and on arrays equally well, which means we're more likely to use it and get the code right the first time.

private static void printStringArray(String[] aList) {
    System.out.println("The enhanced for can also work on array types:");
    for(String s: aList) {
        System.out.println(s);
    }
    System.out.println();
}

It actually took me a while to get used to using this loop structure, because I spent so much time supporting code that had to run in 1.4 level JREs.  In order to ensure the best compatibility I was also compiling with a 1.4 JDK so I didn't have access to this feature.  I'll tell you what, I was really missing out.  My fingers are probably a couple of millimeters shorter than they should be because of all the wear and tear from the extra typing I did.  I for one am glad we have this loop available, and you probably should be, too.

View Code


Wednesday, November 11, 2015

Stop giving me so much static

Let's talk about the keyword static for a moment.

There are two different uses for this in our code.  It can be applied to methods or it can be applied to variables.

When static is applied, it disassociates the item being declared from any specific instance of the class.  For methods, this means that the method can be called by anyone at any time without creating a new class of that type.  This can be particularly handy for utility functions, initializers, or any other chunk of code that wants to run without caring that it's about a particular person, bill, or list of stocks.  For variables, it mostly means that the value is shared across all instances of the class.

Static Methods

Static methods can be called without making a new class.  For instance, it could be used for a factory method, which is a design pattern that calls for objects to be built by calling a function to do so.

public class Person {
    ...
    public static Person createPerson(firstName, lastName) {
        ...
    }
}

You can call createPerson without having a Person object, like so:

Person.createPerson("John", "Doe");

Many utility functions are declared as static, and as a general rule they will need to operate free of any context supplied by objects.

Static Variables

Static variables come from the same basic idea of being disassociated from any specific instances of the class.  They're useful for maintaining overall context, for instance, if we want to keep track of how many Person objects we've created we could write something like this:

public class Person {
    ...
    private static int numberCreated = 0;
    ...
    public static Person createPerson(firstName, lastName) {
        ...
        numberCreated ++;
        ...
    }
}

Now, every time we invoke createPerson, we'll also be incrementing the value of numberCreated, and it will always be available as a statistic our programs can check.

Many times, inexperienced programmers will overuse static methods, because when they first start creating methods and functions, they just call them from main.  Your main method has to be static, and if you try calling non-static methods directly from it, the compiler complains.  So the path of least resistance is often seen as just making those other methods static too.  This does seem to work, but it goes against object oriented design principals, and it's best to nip this in the bud.  So they start with this:

public class OutputTest {
    ...
    private PrintStream outputStream = ...;
    ...
    public static void main(String [] args) {
        print("This is a test");
    }
    ...
    public void print(String message) {
        outputStream.println(message);
    }
}

But that fails because you can't call 'print' from a static context, so they change it to this

public class OutputTest {
    ...
    private PrintStream outputStream = ...;
    ...
    public static void main(String [] args) {
        print("This is a test");
    }
    ...
    public static void print(String message) {
        outputStream.println(message);
    }
}

That fails, too, because outputStream isn't static, so they change the code again:

public class OutputTest {
    ...
    private static PrintStream outputStream = ...;
    ...
    public static void main(String [] args) {
        print("This is a test");
    }
    ...
    public static void print(String message) {
        outputStream.println(message);
    }
}

And they're satisfied.  Everything works now!  I call this the static cascade, and I recommend avoiding it.  If you did not originally intend for these items to be shared and free of binding to specific objects, then don't go changing them to act that way.  

Get used to writing object oriented code.  Do this instead:

public class OutputTest {
    ...
    private PrintStream outputStream = ...;
    ...
    public static void main(String [] args) {
        OutputTest test = new OutputTest();  //The key!
        test.print("This is a test");
    }
    ...
    public void print(String message) {
        outputStream.println(message);
    }
}

While it might be a bit more of a conceptual leap, it's actually a far smaller change to the original code, and it opens your class up to being more adaptable to use in other systems.  It's also a necessary step towards object oriented thinking, so you might as well get it over with now.

It's the final countdown!

Many times we declare a variable that we really ought not to change, at least in some particular spot.  We can just remember not to change it, and that might work.  A better solution is to let the language keep us from even trying, and Java offers us the final keyword for this purpose.

A variable declared as final cannot be changed, so maybe the word 'variable' does not even really apply, so we can call them 'constants' if we like.  This has a couple of different purposes.  First off, we might want to set up a constant like an approximation of pi for use in a class that does geometric calculations:

static final float pi = 3.14159;

Now any code that tries to change pi will be flagged by the compiler as a problem.

Another use for the final keyword is to make sure that methods don't modify parameters we've given them:

public void calculateValue (final int quantity) {

This would make sure that we don't accidentally change quantity somewhere inside the calculateValue method.

The compiler is able to simplify the code that it generates for variables declared as 'final', so we get that benefit, too.  In short, it's a good idea to declare things as final whenever it's reasonably possible to do so.

Tuesday, November 10, 2015

I tried to print my array but all I got was gobbledegook!

This is inspired by a post at /r/javahelp.

A user posted that they were trying to print a sorted array to the console with System.out,println, and that instead of anything that made sense they got [I@4969dd64...  So clearly something was wrong and the array was not being sorted.

But that's faulty troubleshooting, as one could tell by just trying to print the array before sorting.  You would see basically the same thing.

The reason for this is that when you do a System.out.println on any object, what you're actually doing is calling 'toString()'.  If you are printing your own objects for which you've created nice methods that override the default toString, you get nicely formatted output.  If you're using an ArrayList you get a nice, comma separated list enclosed in square brackets.

Arrays are more primitive than that.  Their default toString is just the one from Object, and it does nothing more than tell you where in the heap the object is located.  This is good for verifying that something isn't null, but useless for determining the content.

If you want to see the contents of the array, you've gotta do the work yourself, my friend.  And it's not difficult at all.  This, for instance, will work for any array of Objects that themselves support a reasonable version of 'toString':

public static String arrayToString(Object[] theArray) {
    StringBuilder output = new StringBuilder("[");
    for (Object o:theArray){
        if (output.toString().length() > 1) {
            output.append(",");
        }
        output.append(o);
    }
    output.append("]");
    return output.toString();
}

View code

Tuesday, February 10, 2015

It's a SERIES OF TUBES!

I've been struck in recent days by a number of posts over at /r/javahelp, all with the same basic theme.  They've got some code, and it references a variable name that is declared elsewhere in the program.  These nascent developers don't yet understand that just because you mention a variable in one place, that doesn't mean it's available elsewhere.

It is fundamentally important to understand the issue of scope if you ever hope to write programs well.  Where you declare things, and what keywords you use when you do so, have a huge effect on the visibility of your variables.

For instance, I often see issues that boil down to an attempt at doing this:

void multiplyTwoNumbers(int numberOne, int numberTwo) {
    int numberThree = numberOne * numberTwo;
}

"It doesn't work" they say, or "it doesn't do anything".  My friends, it does exactly what you told it to.  It's just that you didn't tell it to do anything particularly useful.  When this method is finished, it will have multiplied numberOne by numberTwo and assigned its value to numberThree.  Then it's done.

Some folks go a bit further:

void callingMethod() {
    int numberThree;
    multiplyTwoNumbers(5,10);
    System.out.println("See?  It didn't work! " + numberThree);
}

And they're right, it didn't.

The reason is that the two variables named 'numberThree' are entirely independent of each other.  One of them is really 'callingMethod->numberThree' and the other one is 'multiplyTwoNumbers->numberThree' and they have never met.

Naming things the same is meaningless.  It might help us to understand our code better, but as far as Java is concerned the variables might as well be called Ben and Jerry.  Mmmm, Ben and Jerry.

If you really want callingMethod->numberThree to take on the value you calculated in 'multiplyTwoNumbers' you need to explicitly lay it out.  Just as you can't expect your sink to drain properly into the sewer system if you don't actually provide a continuous connection, you can't expect what one method does to just be known by another method.

So make sure you declare multiplyTwoNumbers as an int.  Make sure you actually return the value of numberThree at when it's done:

int multiplyTwoNumbers(int numberOne, int numberTwo) {
    int numberThree = numberOne * numberTwo;
    return numberThree;
}

That will help.  You've now installed the pop-up drain thingie in the bottom of the sink bowl.  Let's finish the job:

void callingMethod() {
    int numberThree;
    numberThree = multiplyTwoNumbers(5,10);
    System.out.println("It verks! " + numberThree);
}

This is so important to understand.  Local variables go away as soon as the local block (code between { and }) comes to and end.  If you don't provide a method for the value to escape the block, it's going to go to the big heap in the sky.

Perhaps part of the problem is that people get confused by the fact that they can do this:

public class Wizz {

    int wizzLevel = 0;

    public void bumpWizzLevel() {
        wizzLevel = wizzLevel + 1;
    }

    public void displayWizzLevel() {
        System.out.println("Current level: " + wizzLevel);
    }
}

Yes, that's perfect valid.  In this case, 'wizzLevel' is an instance variable of the class Wizz.  Every copy of Wizz you create has its own wizzLevel, and all methods within Wizz can reference or change it.

The key of course, is to look at the brackets.  Note that 'int wizzLevel' is inside the brackets for the class as a whole, so it's in scope everywhere within the class.

The key takeaway is that when you want to understand where  a variable is available to you, you need to understand that so long as you are still inside the same set of brackets where it was declared you should be good to go.

{
    int outside;
    {
        int inside; //outside is still available
        {
            int wayInside; //inside and outside are still available
        }
        //wayInside is gone
    }
    //inside is gone
}
//outside is gone

Wednesday, December 3, 2014

Inheritance Part 1 - That Class is Super!

I would like to discuss the concept of inheritance, and no, I don't mean the vase that Aunt Gladys left you in her will.

When we talk about inheritance in object oriented programming languages, we are talking about how one object can be based on another object.  In Java, we use the keyword extends to do this.

However, in order to make this as simple as possible, let's ignore even that keyword for a moment.  EVERY single Java class automatically extends the class Object without any effort at all on your part.

Let's look at an example Person data object, which I will continue to use as an example for future posts.

public class Person {
    private String firstName;
    private String lastName;

    public Person(String newFirstName, String newLastName) {
        firstName = newFirstName;
        lastName = newLastName;
    }
    ...
}

As I mentioned above, Person automatically extends Object, so in reality the class definition is really more like this:
    public class Person extends Object {

But we just don't bother writing it.  We call Object the superclass of Person and Person is called a subclass of Object.

As far as what this brings to the table, let's use what is perhaps simultaneously one of the most common features and one of the most common issues people have with objects when they are starting out.  Printing them out.

If I create a new Person object and want to see what it looks like, I might be tempted to do this:

    Person joe = new Person("Joe", "Blow");
    System.out.println(joe);

If I do this, I will be sorely disappointed when I run my program, because while I might expect to see this:

    Joe Blow

I will instead see something like this:

    Person@4f1d0d

At this point, I begin to tremble and sweat.  In a panic I turn to stackoverflow.com or /r/javahelp and complain that my object is broken and my printouts are garbled.  The regulars there probably make fun of me for not actually posting my code correctly or something.  My dog bites me and my girlfriend refuses to go out with me.  OK, I may have exaggerated a bit.

But what's happening here is that when you call 'System.out.println(joe)' you are (again, invisibly) actually in effect calling 'System.out.println(joe.toString())'.  After all, you need to turn your object into something that can be displayed on the console.  

You might at this point be saying to yourself "But wait, I don't have a 'toString' in Person" and in a sense you're right.  You certainly didn't create such a thing.  But you did in fact inherit a toString method from Object.  Object is pretty ignorant about your code, though, and has no idea how you intend to format your printouts, so it just tells you the type of object and where in your JVMs memory that object is stored.  In general, if a superclass contains a method, a subclass can call it as though it were a part of the subclass itself.

This is all inheritance really is, in the end.  If we try to call a method or refer to a variable in an object, and it isn't mentioned in that object, the compiler tries to see if it's available via inheritance.  If so, you avoid compile errors and things 'work'.  They may not work the way you want, but at least something interesting happens.

Let's fix the problem now.  I could take the cheap and easy way out like this:

    System.out.println(joe.firstName + " " + joe.lastName);

And that would work.  But honestly, all we really need to do is create our own 'toString' method in Person that does things the way we want.  This will save us the effort of having to write the above code everywhere that wants to just display someone's name.  You'll really appreciate that when you decide that you'd rather display that guy as "Blow, Joe" instead and have to change code in 23 different places.

Add the following block of code to Person:

public String toString() {
    return firstName + " " + lastName;
}

And just like that, the original program will print the name out the way you wanted it to in the first place.

There, you've done it.  You've made use of an inherited method, and then you created an override for it.  An override is nothing more or less than specifying that instead of using the method found somewhere up the line of inheritance, you want to use this specific method instead.

When it comes down to it, overriding toString is just the tip of the iceberg, and I will of course be revisiting this later on.  There are some extremely interesting things that you can do with inheritance, and it forms the basis for many important language structures.  For now though, just remember that one class can extend another one, and that when it does so it has the option of replacing methods in its superclass with its own more specific version.  There are a few other rules you'll need to follow, but most of them are not too horrible to deal with.

Monday, November 24, 2014

Collections Part 2: Map

It's time to talk about the Map.

Sometimes we need to store and retrieve information based on its relationship to other information in a keyed fashion.  There are a lot of reasons for this, but for the purpose of this post we'll pretend that we want to store product descriptions based on item numbers.

So I have a store, where I sell an eclectic group of items:

Item #Item Name
100001Tooth straightener
100002Dust Collection
100101Pickled Snail Shell
100201Odor Vent
200001Checkerboard Paint
200101Toenail Fastener

Oddly, business has not been very good lately.

 Now, if I wanted to computerize my system, I might decide that I wanted a way to have the system display the description of an item when the item number was entered (or selected from a list, or something).

 Let me start by saying it would be entirely possible to create two parallel arrays of String variables, such that itemNumbers[0] contains "100001" and itemNames[0] contains "Tooth straightener".  One could search through the first array for the item number for which you were looking, take the index value you found and display the value from the second array.  This can get a bit clumsy, and it would take a lot of work to keep everything in sync, but it could work just fine (albeit a bit slowly when the number of items gets large).  Adding items would be relatively easy.  Deleting them would be annoying, because you'd have to move all the items down.  There are other ways you could do it, too.

But doesn't the following seem quite natural and easy?

    //Get name of item based on item number
    String itemName = products.get(itemNumber);

    //Add new item type to product list
    products.put(newItemNumber, newItemName);

    //Remove obsolete item type from product list
    products.remove(oldItemNumber);

Enter the Map.

A Map is a Collections framework interface designed for just this purpose.  Keyed lookups like this are very handy, and the Map makes it easy to set up, too.

Like List, Map is just an interface.  You will need to create an actual object that implements the Map interface in order to use one, and the most likely candidate is the HashMap.

So your code would look like this:

In the old days, before generics:

    Map products = new HashMap();

Or if you're working in this century:

    Map<String, String> products = new HashMap<String, String>();

The two object types are the key and the value data types, respectively.


Friday, November 21, 2014

Collections Part 1: List

Let's talk about Collections.  I don't mean baseball cards...  or dust.  I'm talking about the Collections framework, which is a powerful set of classes included with your Java distribution.

This is not meant to be an in depth tutorial.  I'm merely going to scratch the surface and give a few guidelines regarding basic use of the framework.

The Collections framework is incredibly important to the Java developer.  You will spend a great deal of time working with the data structures within it.  The two that you will most likely use more than any other are List and Map.

List and Map are not classes.  They are interfaces.  An interface can be thought of as the set of controls for a range of classes.  Much like you might have a gas powered or electric powered oven, you still turn a dial and set a desired temperature.  The interface is the same, although the implementation is different.  This is a key concept:  Code to the Interface is commonly said, and slightly less commonly actually done.  I will do other posts on this idea, it's very important.

Let's start with List.  We'll do Map in another post.

Suppose I wanted to keep track of a few numbers read in from a file.  Each line contains one number, but I don't know how big the file is.  While it would be possible to load the numbers into an array, it would be a bit messy, as I would have to manage the size of the array.  Enter the 'ArrayList'.  This is a Collections based object that works very much like an Array with a turbocharger on it.  I don't have any hard numbers on this, but my suspicion is that it is the most commonly used Collections class out there.

Let's say my pseudocode looks something like this:

Open a file

For each line in the file:

    Read an integer number from the file
    Store the integer in a list for later use

Generate a sum of all the integers in the list as SumTotal
Display SUM to the user

There are multiple paths to success of course, and it's hard to say that any given solution is exactly 'wrong'.  However, unless we know in advance how many values we're going to store, or we wildly oversize the initial allocation, using an array would require us to modify the length of the array regularly.  It's not that this is particularly hard, but it's even easier not to do it.

And let's face it:  One of the secrets of successful programming is doing things the easy way.  It's a hard enough job, there's no reason to add unnecessary bells, whistles and epicycles to our code.

I'm not going to address the bits about reading the file right now, that will be in another post.  I just want to concentrate on 'Store the integer in a list for later use' and 'Generate a sum of all the integers in the list as SumTotal'.

First, we have to create the ArrayList object.  I'm going to do so in a way I haven't shown you before, but it's not too awful to understand:

List<Integer> numberList = new ArrayList<Integer>();

What?

Well, honestly Java can deal with this without having those '<Integer>' parts, but I thought you ought to get used to using them.  They're really handy for preventing certain classes of errors when programs get bigger.

What this is doing is creating a variable called 'numberList'.  It is an object of type 'List', and that 'List' is constrained to hold only Integer values.  That's the reason for the syntax, it makes sure we don't do something silly like try to put a String or a PersonData in there.

List is NOT a class.  You cannot create a 'new List()' directly.  It is what's known as an interface, and essentially describes how to use a category of classes, rather than one single class.

ArrayList IS a class.  You could do this if you so choose:

ArrayList<Integer> sillyNumberList = new ArrayList<Integer>();

This is roughly akin to adding the name of the manufacturer before mentioning an appliance.  Every time.  You wouldn't tell someone to go get you a beer from the Acme refrigerator, you'd just say refrigerator.  The fact that it's an Acme was only important when you bought it (or when you need to have it repaired.  Don't ask me about refrigerator repair, it's a sore spot).  The fact that it's a refrigerator means that you will grab a handle, pull it, and find something yummy and cold inside.  The specific manufacturer does not matter.  Similarly, a List allows you to add items, remove items, look at items and such, all without having to know that it is specifically an ArrayList.

Let's imagine that we've now got a value we want to add as an Integer, in a variable called 'numberToAddToList' (imaginative, huh?)  We'd just do this:

numberList.add(numberToAddToList);

No muss, no fuss, no checking capacity.  Set it and forget it.  You can do this once, or a thousand times or more.  That one line is all you'll need to use.

The other bit we need to work on is generating a sum of the numbers.  The way to do this, of course, is to take all the numbers, one by one, and add them to a variable that started at zero.  I'm going to do this three times here.  The first time using a for loop the way we've already done.  Next, I'll do so using an 'Iterator', which is a helper type designed to go through all the items in a Collection one by one, has been around forever, and is oftentimes a better choice than a standard for loop.  The last is using the 'enhanced' for loops that have been in the Java spec for a few years now.  None of these ways are strictly wrong, but if I was reviewing your code I'd want to see or hear a good reason for not doing it the third way.

Integer sumTotal = 0;

1)
for (int i = 0; i < numberList.size(); i++ ) {
    sumTotal = sumTotal = numberlist.get(i);
}

2)
Iterator<Integer> iter = numberList.iterator();
while(iter.hasNext()) {
    sumTotal = sumTotal + iter.next();
}

3)
for(Integer number : numberList) {
    sumTotal = sumTotal + number;
}


In all cases, we'd just then write:

System.out.println("The total is " + sumTotal);

As I think you can see, the new enhanced for loop makes life pretty easy.  You declare a variable and state where it comes from, and then just use it in the loop.

The iterator probably looks pretty awful to you, and to be fair, that's the cleaned up version available to us since we got to start using Generics.  Back before we could add that <Integer> tag it would have looked like this:
Iterator iter = numberList.Iterator();
while(iter.hasNext()) {
    sumTotal = sumTotal + (Integer)(iter.next());
}

But it was still a useful construct quite often.  Naturally in small examples like these the full impact does not show itself.

List can be used for much more than numbers of course.  Any sort of Object can be stored in a list.  You can have a List of Strings, or a List of Lists, or a List of Maps...

Next time, we'll discuss Maps, which instead of sequential access specialize in looking up specific objects based on a key value.

Wednesday, November 19, 2014

Don't Treat me Like an Object

I originally posted this on Reddit, and got some positive feedback on it, so I thought I would put it up here as an early lesson in object orientation.  That is, after all, our goal here and a dozen posts in I haven't really mentioned it at all yet.

Moving from procedural code to object oriented code is a major leap and takes a real adjustment in thinking.
Very often, multiple pieces of data logically belong together. For instance, a person's given name and family name should generally not be separated. There's little point in having separate references to "John" and "Doe", after all.
This concept existed before object oriented programming did, in the form of 'structures'. In c we'd do this
struct PersonData {
    char givenName[20];
    char surname[20];
}
Which helped some. Now we could declare a variable of type PersonData and pass it around, knowing that the fields would be kept together. Believe it or not that was a big step forward.  Of course a bit of energy was spent on doing things like determining if '20' was enough storage for a name.  
Objects are basically structs with functions added, and with the ability to hide internal details from users of said objects.
So while it would be possible to recreate the above struct as an object like this:
public class PersonData {
    public String givenName;
    public String surName;
}
That doesn't really take advantage of the power of the language yet. Sure, we can now go:
PersonData johnDoe = new PersonData(); //Use default constructor that comes free
johnDoe.givenName = "John";
johnDoe.surName  = "Doe";
But we can do better. For instance, a person ALWAYS has those names, right?  So why allow a PersonData object to even be created without them? Enter the 'Constructor'. It's just a method designed for one purpose: To initialize a new object. We could insert the following into our PersonData class:
public PersonData(String given, String sur) {
    givenName = given;
    surName = sur;
}
And now we could write the earlier code like this:
PersonData johnDoe = new PersonData("John", "Doe");
This PersonData is quite limited as it stands right now, since it's got no methods on it. But you know, that's OK, there's a place for objects that just store data, too. It is, however, a starting point to think about how objects work.
Of course, a constructor can do much more than set values for a few fields, too, performing any sorts of setup and initialization that might be required.
Please note, I am not saying that exposing those variables as public is a good idea, and I would not write them quite that way for a production application, but I'm trying to keep this example simple to understand.

Since whenever you write Java code you're forced to put it into classes anyway, I suggest that you always treat your classes as though they're going to be objects.  Make your main() methods as minimal as possible.  In short,don't do this:

public class InputData {
    public static void main(String args[]) {
        Scanner s = new Scanner(System.in);
        while(s.hasNextLine()) {
        ...

Instead, write it like this from the start:

public class InputData {
    public static void main(String args[]) {
        InputData inputData = new InputData();
        inputData.execute();
    }

    public void inputData() {
        Scanner s = new Scanner(System.in);
        while (s.hasNextLine()) {
        ...

Note that by adding just a few lines I've turned this into slightly more object oriented code.  I've avoided the static cascade problem.  I've also made it so that if I want to I can use this object from some other piece of code without a great deal of trouble.  That code I have in main could be duplicated anywhere.

Tuesday, November 18, 2014

Arrays: A new dimension

Let's revisit arrays and take them quite literally to the next level.

To recap:  An array is a means for storing multiple values of the same kind.  Those kinds can be ints.  Those kinds can be Strings.  Those kinds can be...  other arrays.

The simplest way to think of this is to picture a grid.

int [] [] twoDArray = new int [3][3];

Would generate something akin to this:

012
0
1
2

Each of the empty boxes can hold an int value.

The type of twoDArray[0] is 'int []'.

To process ALL of the cells in this block you'd most likely write a nested set of for loops:

for (int i = 0; i < 3; i ++) {
    for (int j = 0; j < 3; j++ ) {
        System.out.println(i + ", " + j + ": " + twoDArray [i] [j] );
    }
}

Now the grid analogy breaks down just a bit when you make an array more complicated.  For instance, each row could have a different number of columns.  If you were building a more sophisticated application you would probably not want to hard-code the size of the arrays in your loops, but would be more likely to use:

for (int i = 0; i < twoDArray.length; i++) {
    for (int j = 0; j < twoDArray[i].length; j++) {

But the principle is the same.  

By way of example, let's make a table of five rows, where each row has one more column than the last.  We'll populate each cell with the product of the row and column indexes:

int [] [] twoDArray = new int [5][];

for (int i = 0; i < 5; i ++) {
twoDArray [i] = new int[i+1]; //NOTE THIS!  For each row we create a new row of boxes of the correct length.
for (int j = 0; j <= i; j++) {
twoDArray [i] [j] = i*j;
}
}

01234
00
101
2024
30369
40481216

To print out the contents one could simply write this:

for (int i = 0; i < twoDArray.length ; i ++) {
for (int j = 0; j < twoDArray [i].length ; j++) {
System.out.println(i + ", " + j + ": " + twoDArray [i] [j] );
}
}

Which would generate the following output:

0, 0: 0
1, 0: 0
1, 1: 1
2, 0: 0
2, 1: 2
2, 2: 4
3, 0: 0
3, 1: 3
3, 2: 6
3, 3: 9
4, 0: 0
4, 1: 4
4, 2: 8
4, 3: 12
4, 4: 16

It would certainly possible to put this into a more readable format if one wished, of course.

For instance, if you changed the code to this:

for (int i = 0; i < twoDArray.length ; i ++) {
for (int j = 0; j < twoDArray [i].length ; j++) {
System.out.print( twoDArray [i] [j] );
if (j < (twoDArray [i].length - 1)) {
System.out.print(",");
}
else {
System.out.println();
}
}
}

We've introduced something I haven't used before on this blog.  While System.out.println should be familiar, we also have System.out.print.  It's basically the same thing, but it doesn't end by creating a new line.  This gives us the option to add more text after it.  System.out.println() with no arguments just ends the current line of output.

The output from the above would therefore take the following form:

0
0,1
0,2,4
0,3,6,9
0,4,8,12,16

Which closely matches the table up above.  Naturally, if the arrays had been created in a more complex manner the output would reflect that.

This concept can be extended to three, four, or 12 dimensions if you so choose.  Mind you, it gets mighty hard to visualize past three,  Just remember that the content of an array cell can be pretty much anything, including another array.

Monday, November 17, 2014

Arrays of Golden Sun

We've seen processing of simple integer values already, but what if you have to deal with a bunch of them?  Perhaps you have 20 test results and want to do something with them.

I suppose we could write something like this:

int testResult1;
int testResult2;
int testResult3;
...

Then we could write a calculateAverage function...

int calculateAverage(int testResult1, int testResult2, int testResult3..

You know, I'm already tired of typing that, and I've got a whole lot more to go.  And you just know that next year there will be 22 tests, right?

Never fear, we aren't stuck with such awfulness.  Java (as with most languages) supports the concept of arrays.  Don't fear the word, the concept is actually pretty simple to grasp.

First, let's go back and deal with testResult1.  We can think of that variable as being a box that holds a number.  We can put a number in the box, or we can ask the box what number is in it.

testResult1 = 97;  //We've just put 97 into the box

System.out.println("Your first test result was " + testResult1 ); // We've just asked the box what number is in it.

All the operations boil down to one of those.  If we do math, we're just asking what's in the box.  If we reassign the number (like 'testResult1 ++') we're really just asking what's inside, making a new number and putting the new one into the box.  Whatever was in the box before is gone once you do this, there's no room for two numbers.  These are pretty simplistic boxes.

So, I can conceive of 'testResult1' through 'testResult20' as being a row of 20 boxes, each of which I can use to store or retrieve a number.  But man, it's going to be annoying to do much useful work with individually addressable variables like that.

Enter the array.

Let's just take that same row of 20 boxes and relabel them.  In fact, let's glue them together in a long line and give the whole spiel one single label.  We'll call it 'testResults'.

Of course, testResults is not an int.  It's a grouping of 20 ints.  That's going to make it slightly more difficult to do math on it.  Enter the square bracket and the array index.

If we want to refer to the item in the first box, first we have to get over a little hump.  For reasons we do not really need to get into now, just trust me that they're valid, the first box is number 0, not 1.  So, what we previously would have called 'testResult1' can now be called 'testResults[0]'.  It is important to understand that 'testResults' is NOT an integer.  However, testResults[0] (or testResults[13]) IS an integer and is just a marker for one of the boxes in our row.

I know, that seems a bit more difficult at first, but it turns out not to be.  Here's why:

Remember before?  We had to declare testResult1, testResult2, etc. on individual lines?

Well now we can just do:

int [] testResults = new int [ 20 ];

We've specified that testResults is not an int, but an array of ints with the '[]' notation.  We've made it have 20 boxes with 'new int [ 20 ]'.  (This can be done live at runtime, you could do 'new int [ someCalculatedValue ]').  In one fell swoop we've made storage space for 20 individual (but related) integer values.  It gets better.

The 'calculateAverage' function can now be declared like this:

int calculateAverage( int [] valuesToAverage ) {

Well isn't that a whole lot easier?  And you can imagine that before, that calculateAverage method would have had to look something like this:

return (value1 + value2 + value3 + ... + value20) / 20;

Which seems like it takes up a lot of valuable real estate on screen, and, as mentioned before, is irritating to change.

Our new version takes advantage of the fact that the array is indexed (it could do more but I'll talk about that later):

float total = 0;

for (int i = 0; i < 20; i ++ ) {
    total = total + valuesToAverage[i];
}
return total / 20f;

That's the whole thing.  I didn't even get tired.

Of course, this can be improved further.  What if there aren't 20 values in the array?  What if there are 12?  We could change the code, or we could let the array tell us how big it is:

float total = 0;
float valueCount = valuesToAverage.length;

for (int i = 0; i < valueCount; i++ ) {
    total = total + valuesToAverage[i];
}
return total/valueCount;

Now we have a completely generic method for averaging any number of integer values we want, that we will never have to change again.  All we need to do is make sure before using it that the array we're passing in is sized correctly and populated.  We can stash that into a utility class somewhere and use it for years.

Naturally none of this is going to work without stashing numbers in the array in the first place.

One can initialize an array with hard coded values:

int [] testScores = { 100, 95, 22, 84 };

Or one can write code to set the values.  Assuming we have appropriate helper functions in place, this kind of thing could work.  It's more likely that you'd be getting input from the user or a file for your early experiments with the language.  I think we'll talk about those soon.

int [] testScores = new int[ getNumberOfScores() ];
for ( int i = 0; i < getNumberOfScores(); i++ ) {
    testScores[i] = getScore(i);
}

Of course, that's just the tip of the array iceberg, but I think it gets across the main points:

Arrays:

  1. Are just ordered, indexed lists of the data types we already understand
  2. Can be passed as single labels but all the internal values are readily available
  3. Contain 'meta' information about their contents, particularly how many items they hold
  4. Can make many data processing tasks easier to code and understand
If you're having trouble with this concept, please let me know.  It's good to have a firm grounding in basic aggregate data structures like this before we move on to more complex topics.  Much of what we do in programming involves understanding some concept, then not using it directly, but instead using higher level structures that are better handled if you know what's going on underneath.

View Code

The Old Switcheroo

Let's talk about the 'switch' statement for a bit.  This is a form of conditional that is better suited to some tasks than if/else.

First, let's look at the structure of a switch:

switch(variable) {
    case value1:
        //Code to execute for value1
        break;

    case value2:
        //Code to execute for value1 or value2

    case value3:
        //Code to execute for value3
        break;

    default:
        //Code for any value other than the three above

}
// Done with switch

In detail.

If variable is equal to value1, we execute the code under 'case value1', then we 'break', which means we exit the current block (jump to 'Done with switch').

If variable is equal to value2, we execute the code under 'case value2', then continue to execute the code under 'case value3' before we hit the 'break' and head out to 'Done with switch'.

If variable has any other value, we execute the code under 'default'.

This is basically equivalent to:

if (variable == value1 || variable == value2) {
    if (variable == value1) {
        //Code to execute for value1;
    }
    //Code to execute for value1 or value2
}
else if (variable == value3) {
    //Code to execute for value3
}
else {
    Code for any value other than the three above
}

But I think in this case the switch is a bit easier to follow.

Sadly, the switch works with only a limited number of data types.  Basically it will work for atomic types that represent integer values, the objects that wrap those atomic types (like Integer or Long), and String.  It will also work with Enumerations, but I haven't written about those yet...  I guess I should get to those soon.

So, let's combine a for loop with a switch statement to get some output, shall we?

        for (int switchValue = 0; switchValue < 5; switchValue ++) {
            switch (switchValue) {
                case 0:
                    System.out.println("Just starting out.");
                    break;

                case 1:
                    System.out.println("Making progress.");
                    break;

                case 4:
                    System.out.println("All done.");
                    break;

                case 5:
                    System.out.println("We will never get here.");
                    break;

                default:
                    System.out.println("Getting there...");
                    break;
            }
        }


This runs a simple loop that goes from 0 to 4.  Along the way, we run a switch to execute various blocks of code based on that value.  The output from this block of code looks like this:

Just starting out.
Making progress.
Getting there...
Getting there...
All done.

If you follow the code, I hope this makes sense to you.  The 'default' statement catches anything that isn't 0, 1, 4 or 5, so it runs a couple of times in the middle.  If this is not clear, drop me a line and I'll try to improve it.

If I, if I, if I, if I Didn't Love you else I'd Hate You

At this point I'm sure I've written a bunch of if statements in various examples, but I want to discuss a few specifics.

So far, I've used only the simplest form:

if ( someConditionIsTrue ) {
    executeThisCode();
}

It actually doesn't get TOO much more complicated than that, but let's go into it anyway.

Let me just talk about what I mean by 'someConditionIsTrue':  What I mean is that we are evaluating what is within the parenthesis in order to determine whether the Java language considers this to be a 'true' value.  That doesn't mean some kind of universal truth, and it doesn't mean that it knows better than we do.  All it means is that if the language structure causes the boolean value 'true' to come out, we pass the test.  All of the following are 'true' to Java:

true

! false

1 == 1

1 != 53

(1+1) == 2

(1+2) == (4-1)

And it gets more complicated than that.  There are all sorts of expressions one can evaluate for truth, many times they are based on previous work your program has done.  You might for instance have a user enter their birth date, compare it against the current date, and decide that 'true' means 'older than 21 years'.  All you have to do is construct the expression correctly in order to suit the language's ability to decide based on what it considers to be truth.

OK, but what if someCondition ISN'T true?  The block doesn't execute, and we go on to the next line after the closing bracket, right?  But what if we want to do something because the condition is not true?

I guess we could do this:

if (conditionIsTrue) {
    doStuff();
}

if (conditionIsTrue == false) {
    doOtherStuff();
}

In fact, that would work fine.  Of course, if 'doStuff()' as a side effect changed the condition to false you would wind up executing both blocks.  I mean sure, doStuff() SHOULDN'T change that value, that's bad practice, but as an old C programmer I know very well that "shouldn't" doesn't necessarily mean "doesn't".

Besides, there's a cleaner way to express that concept:

if (conditionIsTrue) {
    doStuff();
}
else {
    doOtherStuff();
}

Isn't that better?  It makes the intention clear, it's less prone to side effects, and you finally get that one joke some programmer made on that forum you don't want anyone to know you visit.

You use 'else' to do things when the condition in an 'if' statement is false.  This will come in handy, and I'm sure I'll be using it soon in examples, so I wanted to make you familiar with it.

Another thing I should point out is that sometimes we need to make decisions based on not just simple true/false values, but combinations of such values.  maybe a user can be considered a 'favored customer' if they have either been a customer for two years or they have spent at least $1,000.00 with us.  That's where we get into what is called 'boolean logic'.  This is not too difficult to understand, and it's critical to get it locked down into your memory.  Please see the earlier post 'Hooray for Boo...leans' to get more information about this.  Just understand that almost anywhere that we can do a simple check for true/false, we can probably extend it to a more involved expression involving multiple terms combined in various ways.



View code here