Showing posts with label TYPE. Show all posts
Showing posts with label TYPE. Show all posts

Friday, 21 September 2012

Java's Assignment Operators

An assignment operator is a way of putting a new value into a variable.

I covered these briefly in Doing Math in Java, Part 1. Now I'll go into a bit more detail.

The Simple Assignment Operator

The simple assignment operator is =.

It places the value from the expression on its right side into the variable on its left.
This is covered in detail in Left Becomes Right.

Also see the Java Language Specification: The Simple Assignment Operator.

The Compound Assignment Operators

The compound assignment operators are:
+=, "plus-equals",
-=, "minus-equals",
*=, "times-equals" or "star-equals",
/=, "divided by-equals" or "slash-equals",
%=, "remainder-equals" or "percent-equals",
&=, "and-equals",
|=, "or-equals",
^=, "exor-equals" or "caret-equals",
>>=, "signed-shift-right-equals",
<<=, "shift-left-equals",
>>>=, "unsigned-shift-right-equals".

Commonality
Each of these operators has a variable to assign a value to before it, and an expression that results in a value after it:
variable operator expression

The expression has to result in a value that is compatible with variable's type.

Java will calculate the value of expression,

perform the calculation variable optype expression, where optype is the assignment operator without the equals sign.

Then it will place the result of that calculation into variable.

+=, "Plus-Equals"
Plus-equals adds the value after += to the original value of the variable, then puts the result into the variable.

-=, "Minus-Equals"
This subtracts the value after the operator from the original value in the variable, then stores the result in the variable.

*=, "Times-Equals"
Multiply the variable by the value on the right of the operator, put the result in variable.

/=, "Divided by-Equals"
Same as the above, but for division.

%=, "Remainder-Equals"
This finds the remainder of the variable's initial value divided by the value after the operator. That remainder is then put into the variable.

See Java's Modulo Operator--Wrapping Around for more information on how the remainder (or modulo) operator % works.

&=, "And-Equals"
And-equals does a bit-wise AND of the value after the assignment operator with the original value of the variable, then puts the results in the variable.

|=, "Or-Equals"
Or-equals does a bit-wise OR of the variable and the value after the operator. The result is placed in the variable.

^=, "Exor-Equals"
Exor-equals is short of Exclusive-Or Equals (and it is often written xor-equals). It does a bitwise exclusive-or of the variable and the value after the assignment operator, then puts the result into the variable.

>>=, "Signed-Shift-Right-Equals"
This does a signed right shift of the variable a number of times equal to the expression after the assignment operator. The result is placed in variable.

<<=, "Shift-Left-Equals"
This does the same thing as signed-shift-right-equals, except it does a signed left shift (each bit in the variable gets moved to the left expression times.

>>>=, "Unsigned-Shift-Right-Equals"
This one moves all the bits, unlike the signed shifts which leave the sign bit (highest order bit) alone.

Not Quite the Whole Story
That covers how these operators behave with numerical and other simple values. These operators have other behaviors when used with Strings, Arrays, and other complex value types. That goes beyond the scope of this article, however, more on that can be found at the links given under "Additional Information".

Additional Information
See the Java Language Specification: Compound Assignment Operators, Multiplicative Operators, Additive Operators, Bit-wise and Logical Operators.

Java Introspection and Using Collections without Generics

In my prior article on Generics we looked at how to use Generics to associate at type with data stored in a Collection.

You might wonder why would anyone want to store information in a Collection without its type being preserved. Well, it's possible that you'd want to store many Objects of different types in one collection. In that case, the only parent those types might have in common is java.lang.Object. So using a Generic won't do you any good.

But, once you pull that data back out of the Collection, how do you find out what it was?

Fortunately, the object itself has that information stored with it.

There are two easy ways to find out what it is. instanceof can test if it is a specific type of Object:
if (anObject instanceof String) { aString = (String)anObject); }


You can also have an Object tell you its type:
Class myClass = anObject.getClass();

or
String myClassName = anObject.getClass().getName();


A look at the documentation for Object and Class gives all sorts of useful methods for dealing with classes of data objects in Java.

Here's some sample code:
import java.util.*;

public class NoGenerics2{
// This is an example of using introspection
// to determine types of Objects stored in a
// Collection without a Generic declaration.

  public static void main(String[] arg){
    ArrayList myList = new ArrayList(); // No Generic  declaration.
    String myString="Boss Moss";
    String yourString="Snorkledorf";

    // put the strings into the List
    myList.add(myString);
    myList.add(yourString);

    for (Object anObject: myList){
      System.out.println(anObject.getClass().getName());
      if (anObject instanceof String){
        String aString = (String)anObject; 
      }
      else{
        System.out.println("Not a String, Sheriff!");
      }
    }
  }
}

Generics in Java

Generics are an oddly-named thing in Java that associate objects stored in a Collection with a particular type. Let's take a look at a piece of code that uses a Collection to store some Strings. It uses an ArrayList. Here's the code:

import java.util.*;
public class NoGenerics{
// This is an example of what happens 
// when you don't declare a class
// for a Collection using Generics. 
// It won't compile!

  public static void main(String[] arg){
    // No Generic  declaration.
    ArrayList myList = new ArrayList();
    String myString="Boss Moss";
    String yourString="Snorkledorf";

    // put the strings into the ArrayList
    myList.add(myString);
    myList.add(yourString);

    for (String aString: myList){
    // We can't do String methods on the items from myList.
      if (aString.startsWith("Boss")){
        System.out.println(aString + ":");
        System.out.println("Make sure you spell it right!");
      }
      else{
        System.out.println(aString + ":");
        System.out.println("I am so pretty!");
      }
    }
  }
}

What happens here to upset javac is that once the String is placed in the ArrayList, its type is lost, and it is known only as an Object. To be treated as a String again, it would have to be cast as a String. If any errors are made in casting the data, the program will fail at runtime, not when it is being compiled--when the programmer has it in their hands to fix it.

Feel free to take the above code and try to compile it to see the error you'll get. It is instructive.


The Fix for Lost Types

In Java version 1.5 "Generics" were added to fix this. Now Collections like the ArrayList can associate a type with the data put in them, and the compiler can do type checking. Here's the above code, with the Generic declaration added:

import java.util.*;

public class Generics{
// This is an example of what happens 
// when you declare a data class
// for a Collection using Generics.

  public static void main(String[] arg){
    // Generic  declaration.
    ArrayList myList = new ArrayList();
    String myString="Boss Moss";
    String yourString="Snorkledorf";

    // put the strings into the ArrayList
    myList.add(myString);
    myList.add(yourString);

    for (String aString: myList){
    // Now when we can do String methods on the List items.
      if (aString.startsWith("Boss")){
        System.out.println(aString + ":");
        System.out.println("Make sure you spell it right!");
      }
      else{
        System.out.println(aString + ":");
        System.out.println("I am so pretty!");
      }
    }
  }
}

Generics = Typed Collections
So if you are going to use a collection on Objects all of a specific type (rather than mixing and matching), put on a Generic declaration.

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"

Your Own Java Classes

To use Java effectively, you want to create and use your own classes. This is one of the great powers of object-oriented languages--the ability to construct programs out of independent building-blocks that cut large problems down into small, easily solvable ones. There's a lot more that can be said, and much of it is elsewhere. So I'll get right into a very simple, very basic example here.

We're going to create a very simple object class that will print a "Hello" message to the screen when called. This class will have two different methods that will do the same thing, though we'll vary the messages they print a bit so that we can see which one is doing the work.

Here's our class: (download HelloClass.Java)

public class HelloClass{

/**
 * sayHello() prints "Hello!" to the Java console output.
 */
 public void sayHello(){
  System.out.println("Hello!\n");
 }

/**
 * doHello() prints "Hello, hello!" to the Java console output.
 * It's static, so you don't need to instatiate a HelloClass 
 * object to use it.
 */
 public static void doHello(){
  System.out.println("Hello, hello!\n");
 }

} // End of HelloClass


The two methods we have to print messages are sayHello() and doHello(). To use sayHello(), we need to have a HelloClass object created, then call that object's sayHello() method.

doHello(), however, is a static method. This means is belongs to the class, not to any object of the class. So we can use it without any HelloClass objects being created first.

Here's a class that uses these methods as described: (download UseHello.java)

public class UseHello{
 public static void main(String[] arg){

  // We can use doHello() without a HelloClass object:
  HelloClass.doHello(); // call the HelloClass's doHello() method.

  // But we need to create a HelloClass object to use sayHello():
  HelloClass hello=new HelloClass();
  hello.sayHello(); // call hello's sayHello() method.

 }
} // End of UseHello.


If we try to call sayHello() without first creating a HelloClass object, like this:
HelloClass.sayHello();

then we'll get the dreaded "calling a non-static method from a static context" error message. That's letting you know that you need to instantiate (or create) a HelloClass object first, then tell that object to call its method.

Static methods are useful for things like general arithmetic and calculation or other methods that might be used in a way where state information is unimportant. But beware, it's easy to create static methods when what's really wanted is an object that does what you want.

Friday, 14 September 2012

Reference Types: Names and Objects

When we learned about primitive variables we learned that they are a way of storing a simple value, like a number or a true-false state. We give them a name, and whenever we want to get that value we use that name. Whenever we want to change the value that's stored, we set the name equal to the new value:

int value;     //Declare an integer variable named value.
value=100;     // Store the number 100 in value.
System.out.println(value);  // Print the number in value, "100"
value=20;     // Put 20 in value. Over-writes the 100.
count=value;     // Gets the number from value and puts
        // it in count.
        // Assumes 'count' was declared as an int before.

When we use objects, we're using a more complex kind of variable. We don't do it for the sake of complexity, but because adding some complexity here makes things a lot simpler elsewhere in our program. A lot simpler.

Object variables are called "reference types", the type is actually the class that the object belongs to. The difference between a reference variable and a primitive variable is that a primitive variable actually is a storage location in computer memory that holds the stored information. A reference variable is a name that names a specific type of information. It doesn't actually hold the information, it's just associated with an object that actually holds the information.

This why there's a two step process in creating a Java variable. The first step, declaration, sets up a name we're going to use for a particular type of object. The second step, initialization, associates that name with an object--creating a new object if necessary.

Let's say I'm talking to a friend. I say, "I'm going to get a hamster and call it Wilmot."

"That's nice," says the friend. "Can I see Wilmot?"

"I don't have him yet."

"What color is Wilmot?"

"I don't know, I don't have a hamster yet."

Then I go to the pet store and pick up a hamster. I call him Wilmot, put him in a cage and take him home. I've now initialized the name Wilmot I declared to my friend earlier to point to a specific hamster.

Now when my friend says "Can I see Wilmot?" I can show him a hamster, and say "This is Wilmot." When he wants to know the color, there is an object to get the color of.

In Java terms, if I had a Hamster class, I could declare a name like this:

Hamster wilmot;

I now have a name for a Hamster object, but no Hamster. I can initialize the reference variable by getting a new Hamster object using the class's constructor, Hamster():

wilmot=new Hamster();

Now I have a Hamster object associated with the name. The name references the Hamster object that's been created. Hence the term "reference variable".

Now, if I create a new name and make it point to the same Hamster object, it becomes a new name for the same object:

Hamster fluffy;
fluffy=wilmot;

Now, if I make any changes to fluffy they also happen to wilmot. For example, if wilmot's size is 10cm, and I set fluffy's size to 12cm, then get wilmot's size it will be 12cm.

This is different from what happens with primitive variables. If I do the same thing with a pair of primitive variables like this:

int value, count;
value=100;     // Initialize value to 100;
count=value;     // Set count equal to value.
count=count-20;     // Subtract 20 from count.
        // We could have said 'count-=20;', too.
System.out.println("value= " + value);     // Print value.
System.out.println("count= " + count);     // Print count.

Then the output will be:

value= 100
count= 80

With a primitive variable, when we set it equal to another primitive we get a copy of the value in that primitive's own storage. When we set a reference variable equal to another reference variable, we are now referring to the same object as the other reference variable. In pet terms, it's like giving our hamster a second name. We might call it wilmot or fluffy, but they're both the same hamster.

If we need to have each name apply to a different hamster, we need to go back to the pet store for another hamster. In Java, we need to use the constructor to get another Hamster object:

Hamster wilmot, fluffy;
wilmot=new Hamster();
fluffy=wilmot;     // fluffy and wilmot are now both names
    // for the same Hamster object. Anything we do to fluffy
    // will also apply to wilmot, and vice versa.
fluffy=new Hamster();
// Now fluffy applies to a different Hamster object.
// We can make changes to fluffy and
// they won't affect wilmot. We now have two
// Hamster objects, each with its own name
// to refer to it.

But what if we want it to act like a primitive object? What if we want a copy of wilmot to make changes to without affecting wilmot? Then we use a method of the object's class to create a new object that's a copy of that object. Usually this will be clone():

Hamster wilmot, fluffy;
wilmot=new Hamster();
fluffy=wilmot.clone();

Now fluffy is a copy of wilmot, and we can make changes to fluffy without affecting wilmot. Note: whether a class has the clone() method varies from class to class. Normally, if the class implements the Clonable interface then it has a clone() method that works this way.

The void Type


void can be the most confusing type. It's an odd word to start with. It's part of the long string of words that appear before the word main in the declaration of that method.

Void means 'empty' or 'nothing'. In the case of a Java method, it means that that method returns nothing:

public void drawTriangle(){ ...

This is as opposed to a method with another type, which returns an object of that type:

public int sum(int a, b){
  return a + b;
}

This returns an int object to the caller:

int count1, count2, amt;
...
amt=sum(count1, count2);

Why would you want a method that returns nothing? Because often you have methods that do something that doesn't affect the state of the program itself. Drawing something is an example of this. A method that draws something makes its results obvious in what it draws. It doesn't need to pass any information back to the other parts of the program. Instead it is expressing the state of the program to the outside world. 

Primitive Variables: Sticks and Stones

In Java there are two types of variables. The simpler type are called "primitive" variables. This makes it sound like you'd only want to use them in programs for, say, starting fires or skinning cave bears. They're actually used in almost every program, and are very powerful.

There are eight types of primitive variable, each one holds a different kind of information. The types are:

boolean--holds a true or false value.
byte--holds an integer value from -128 to 127.
short--holds an integer value from -32768 to 32767.
int--holds an integer value from about -2 billion to 2 billion.
long--holds integer values too big for int.
float--holds a normal-precsion floating point number.
double--holds a high-precision floating point number.
char--holds one character (one letter or digit or punctuation symbol.


Two Steps to Making A Variable



There are two parts to creating any type of variable; declaration and initialization. In declaration you're giving the variable a name, and telling Java what type of variable it is:

int bugs;

In this statement, we've created a variable named "bugs" and told Java that it's an int (normal integer) variable. The name can be whatever you want it to be so long as it's not one of Java's keywords. You can look up Java's keywords in the Java Language Manual available online at Oracle's Java reference site.

A variable is initialized by giving it some value. In the case of a primitive variable, it's simple:

bugs=0;

You can get away without initializing primitive variables in your program, but it's a bad practice. By putting a specific value in the variable in your program, you know what's in your variable before you start using it.

The declaration and initialization can be combined into one statement, and most programmers do this most of the time:

int spiders=0;

You can also declare multiple variables in one statement by putting the declarations (and initializations) in a comma-separated list:

int frogs=0, salamanders=100, newts=3;

You can add linebreaks and whitespace to make longer lists more readable:

char
cow='c',
horse='h',
pig='p',
duck='d',
goose='g',
snake='s';

Many methods can work with primitive types as arguments. For example, println() can have any of the primitive types in it, and it will print them out appropriately:

System.out.println(cow);

Prints:

c

System.out.println(salamanders);

Prints:

100

You can define new colors for graphics in the color class using int variables:

Color amphibianColor = new Color(frog, salamander, newt);

or float variables:

float red=0.95, green=0.98, blue=0.0;
Color lightAmber = new Color(red, green, blue);


(These Color statements are a preview of the declaration and initialization of the other type of variable, reference variables.)