Friday, June 24, 2011

Java Variable Value Assignment: Left Equals Right, Left Becomes Right

One of those things that vexes beginning programmers is assigning values to a variable in Java. Part of what makes it so vexing is that the problem is practically invisible to an experienced programmer. Another part of it is that we use the equals sign (=) to do the assignment.

Take a look at these statements:

int i = 1;
j=7;
7+count=c;
b+14=a+9;

The first two are fine (assuming that 7 is a valid value for whatever type of variable j is), but the last two are wrong.

Remember All That Algebra We Taught You? Well, We Broke It.

After you've gone to all the trouble to learn how to deal with things like 7+count=c and b+14=a+9 in algebra class, now we take what you know and turn it on its ear in programming class. Sweet, eh?

The problem is that the = we use in programming has pretty much nothing to do with the = that you use in math. It's just close enough to be confusing. In Java, the equals sign is an assignment operator, not an indicator of equality between values as it is in math. There is a comparison operator for equality in Java, it's ==, and we'll talk about it shortly. First, let's talk assignment.

Assignment

In computers, we use the term assignment to describe sticking a value into the computer's memory so that we can get it back later. It's like using the memory in a programmable calculator. We put some number into our calculator's memory so that we can get it back later for another part of our calculation. It's pretty much the same thing with computers.

With Java, we can store all kinds of values, not just numbers. We can store sections of text, called strings in a String variable, for example. (Java prefers the term "member" over variable, in general. For what we're talking about now, the two terms are interchangeable.) We can also store more than one thing at a time, like all the information about a bicycle in a Bicycle object that keeps track of a bicycle's color, frame size, tire size, gear ratios, etc., all together in one object.

But we're here to just look at assignment today, not the wide variety of things we can assign as values.

To store a value on a calculator, you use some key sequence like M+ or STO 00 to store the value in the calculator's display to memory. With Java, we use the equals sign to store some value on the right into whatever is on the left side of the equals sign. We read from left to right like this:

count = a;
"count equals a"

This means we take the value of a and place it in count. But a better way to read that equals sign is to use the word "becomes" instead of "equals":

count = 9;
"count becomes nine"

This makes it more obvious that we're putting in a new value that changes the value of count. In this case, we're putting in a value of 9. The statement up above would be "count becomes a" or, better yet, "count becomes a's value." Because what we're doing in count= a; is taking the value in variable a and copying it into count. If we then print the value in count, it will be the same as whatever is in a at that time.

We can also compute a value to put into our variable.

count = a + 1;
"count becomes a plus one"

This makes the value in count be one more than the current value of a.

What we can't do is change sides around the equals sign. In algebra, c = a + 1 is the same as a + 1 = c. But in Java that doesn't work:

a + 1 = count
This is wrong in Java. Does not compute. Norman, Norman, help me Norman!

We would be trying to make a+1 become the value in count. The problem is, you can't have a storage location named "a+1". Java doesn't see this the way your algebra trained eyes do.

Comparisons

In normal math, when we use the equals sign we are making a comparison. We are stating that what's on one side of the equals sign is the same as what's on the other side. For most algebra problems, we assume that the statement is true and try to find values for the variables that result in that.

Another use of equals in some math problems is to state that two things are equal when they may or may not be, then determine whether that statement is true or not. You remember those problems, they looked something like this:

State whether each of the following is true or false.
1. 11 = 6 + 5
2. 14 = 3 x 7
3 65 - 14 = 17 x 3


In Java, the equals sign is already used for assigning values to variables. How do we do a comparison to see whether it's true or not?

The == Operator

In some languages, = does both jobs. But in Java, there's a second operator for doing equality comparisons, ==, "equals equals". When we want to see if two values are the same, we compare them using a statement something like this:

if (count == 100) then stop();

This compares count to the value 100, and executes the method stop() if the result of the comparison is true.


The Dangers of the = Operator

Something to look out for is using = by accident in such a situation. Like this:

if (count = 100) then stop();
Don't do this if you want to compare count to 100!

What this does is assign the value 100 to count. If the assignment is successful (which it almost certainly will be, if the program compiles), the program will then do stop() every time it hits this statement! Because the assignment was successful, so the result is considered to be true.

Summary

The equals sign makes the variable on the left equal the computed value from the right side of the equals sign:

name = "Mergatroyd";
"name becomes Mergatroyd"

It doesn't work the other way around (putting something from the left into the variable on the right.)

If you want to compare to values to see if they're equal, use "equals equals":
if (state == "done") then exit();
"if state equals equals done then exit" or
"if state is equal to done then exit"
StumbleUpon

Tuesday, June 7, 2011

Doing Math in Java part 2:Functions

The basics of math in Java using operators was covered in Part 1: Operators. There I went over the standard operations built into the language itself, rather than in its APIs (libraries).

But that's hardly the end of useful math operations. Especially when doing graphics, where all those geometric and trigonometric functions come in so useful. Square root, cosine, absolute values, etc.

If you're wandering into the Java APIs unguided, the java.math package might catch your eye right away. Unfortunately, it's a false trail when what you're looking for is a simple general purpose math package (it's a nice special-purpose math package for particular sorts of calculation, however.)

What you really want is the java.lang.Math class, in the java.lang package.

This has most of the standard math functions you're used to. They're defined as static methods, so you don't need to create a Math object to use them. You just call them like this:

    float distance = Math.sqrt(dx*dx + dy*dy);
float speed = Math.abs(velocity);


These call the square root function Math.sqrt() and absolute value function Math.abs(). There are a slew of others like degree to radian conversion, the standard trig functions, and so on.

Date Calculations

Calculations with dates are another standard sort of math that's not covered by standard operators. In the package java.util we've got the Calendar class. The Calendar class itself is an abstract class. This means that it's a class used to build other classes with, not to use directly. The GregorianCalendar class is a concrete implementation of Calendar that you can use directly. The Calendar object's add() method will add or subtract some amount of time--days, minutes, hours, etc.--to or from a given date (the date that the object is set to:

  1. Create a GregorianCalendar Object

  2. Set its date

  3. Use its add() method to add or subtract the time difference.


Example:
GregorianCalendar myDate;
myDate = new GregorianCalendar(2011, 6, 7); //set the date to 07 June 2011.
myDate.add(Calendar.Date, 165); // add 165 days to that date.


before(), after() and compareTo will return whether one date occurs before or after another. Computing the number of days between two dates is a bit more complex, unfortunately, as are similar calculations. Basically, the procedure is to use getTime() to convert both dates to time values, get the difference, then divide that by the time units you want to see the difference in (e.g. divide by 24 hours periods to get the difference in days.)

Unfortunately, the Calendar class demonstrates one of the problems with much of Java. It's an overly generalized class that prevents simple solutions to many simple and obvious problems. The older Date class took a more direct approach, but it has been deprecated in favor of the Calendar based classes. Unfortunately, even obtaining a printable date value according to the system's current locale takes a fair bit of set up in Java. A better solution would have been a very general class like Calendar behind a more usable class for solving conventional problems, but Java's development got it backward. We got the simple class first, it's inflexibility for solving certain problems resulted in criticism, then came a general class, which is no good at doing simple and obvious things for most users. The extra layer that we should have to make Calendar more usable has not yet appeared in the standard API (and possibly never will.)

So it takes a lot of code to do what should only take a line or two, when working with dates.

Still, give the Calendar and GregorianCalendar class a look-over. Even though it takes some extra code and set-up to do some simple tasks, the solutions to these problems are well established and many examples are available. It's just not as simple as System.out.println(myDate);

I'll be adding articles dealing specifically with dates myself at a future date.
StumbleUpon