Java programming involves manipulating things called objects. The objects are either primitive type objects (usually not called objects) or class objects. Classes and objects model information. Java has a tremendous number of classes (like a large toolbox) for you to use to help the programmer manipulate information.

Java also has primitive types for numbers, character etc. Some Java primitive types are:

int values are 1, 0 -37 etc and operations are + , - , *, / and % examples 37 % 3 is 1, 37 / 3 is 12, 14 % 2 is 0 and 8 / 3 is 2

double values are 1.0 0.0 -37.37 etc and operations are +, -, *, and /

char values are 'a'. '6'. '$', '\n'. '\\' etc

boolean values are true and false and operations are !, && and ||


Class objects are defined by classes. A class is a description of what data and operations a class object can contain. The data in an object are called fields. The operations are called methods. Objects are created by methods called constructors. All constructors have the same name as the class and are called by the reserved word new. If a constructor is not defined in a class, Java provides a constructor.

Examples of classes:

String

data: a sequence of characters

some methods: length, indexOf, charAt, equals

constructor: new String("...") or just "..."


Student

data: a String name and a String id

some methods: add, drop, getSchedule, getName, getId, toString

constructor: new Student(''..name..'',''..id..'');


BankAccount

data: a String id and a double balances

some methods: deposit, withdraw, getBalance, getAccountNumber

constructor: new BankAccount("..ID..");


There are three types of classes



Class variables and primitive type variables are places to save information. For example if we have a String object with many characters then it would be useful to refer to it with a (shorter) name. All class variables and primitive type variables can save only one type of object. The type is "declared" when the variable is given a name. The syntax is

classType variableName; OR primitiveType variableName;

Examples are int count; double balance; String word, Student aStudent, BankAccount myAccount; etc.

The assignment operator = means copy the right side to the left side. So x = 37; means copy 37 to x and name = "FIU" means copy (a reference) to "FIU" to name. The statement

count = count + 1;

means calculate the value of the right hand side (add 1 to the current value of count) and copy it back to count.


The assignment operator can be used with the declaration of a variable. For example:

int count = 0;

BankAccount myAccount = new BackAccount("373737373");


Primitive type variables contain values while class type variables contain references to class objects.

So if we have int x = 37; we can picture this as x | 37| and if we have

String word = "abcdef" we can picture this as word |-----| -----------------> "abcdef"

Before class variables are assigned they refer to
null an invalid reference. Therefore class variables must be assigned the reference of a class object before they can be used. This is typically done using a constructor. Many times the constructor has inputs. (Primitive type variables should also be assigned a value before using them). For example:

ClassName classVariable = new ClassName(...);

where ClassName(...) is a constructor for the class. The ... refers to inputs to the constructor.


Examples:

String word = new String ("abcdef");

String word = "abcdef";

BankAccount myAccount = new BankAccount("373737373");


So a class is a description of what data and methods a class object can have and a class variable contains a reference to a class object which has the data and methods as described in the class. Given the name of a class object we use the dot notation to access the data and methods. The syntax is object.method(...).


Examples:

int len = "Bill".length();

char ch = "abcdef".charAt(3);

double myBalance = myAccount.getBalance();

myAccount.deposit(1000.00);

Student me = new Student(''kraynek'',''37'');

me.add(''ProgrammingOne'',4);


Some classes have static methods. A static method is one the is shared by all objects of the class. A static method can be accessed by the class name; an object of the class is not needed.


Example:

JOptionPane.showMessageDialog(null,"Hello World!");


An example pattern of a main class is

public class SomeClass {
/**
 * @param args the command line arguments

*/

public static void main(String[] args)

        // Statements go here

}

}

All public classes must be in a file with the same name as the class (SomeClass.java in this case).
Only one public class can be in a file.
For example see JOptionPaneHello1.java.


Some methods calculate and return a value (length, charAt and getBalance) and some just do something without returning a value (deposit and showMessageDialog). In general methods that return a value are described by

Return-Type methodName(type1 name1, type2 name2, ...)

and methods that just do something are described by

void methodName(type1 name1, type2 name2, ...)

where type1 name1 etc are the inputs. So the String and BankAccount methods can be described by


int length()

char charAt(int index)

int indexOf(String s)

int indexOf(char ch)

String substring(int index)

String substring(int index1, int index2);


Comparing (relational) operators are == (equal) and != (not equal). These operators compare the values of the variables being compared. So using == to compare primitive types compares their values while using == to compare class type variables compare references. To compare the objects referred to by class variables use the equals method. All classes have the equals method.

Examples:

x == 37

x != y

word.equals("abcdef")

! word.equals("abcdef")

Some String methods:

If String s = "abcdefab"; then
s.indexOf("a") is 0
s.indexOf("b") is 1

s.charAt(2) is 'c'
s.substring(0,4) is "abcd"
s.substring(4) is "efab"

s.substring(2) is "cdefab"

s.substring(1,5) is "bcde"

s.replace(''cde'',''123'') is ''ab123fab''

s.equals(''abcdefa'') is false


See also StringExample1.java , StringExample2.java and StringExample3.java .


Consider the BankAccount class description

public class BankAccount {
 private String accountNumber;
 private double balance;
/** Creates a new instance of BankAccount
 * @param newAccountNumber the id of the customer
 */
 public BankAccount(String newAccountNumber) {
 accountNumber = newAccountNumber;
 } // end constructor
/** Gets the customer's accountNumber
 * @return the accountNumber as a String
 */ 
public String getAccountNumber() {
 return accountNumber;
 }// end getaccountNumber
/** Gets the customer's balance
 * @return the balance as a double
 */
 public double getBalance() {
 return balance;
 }// end balance
/** Process a deposit
 * @param deposit the amount deposited
 */
 public void deposit(double deposit) {
 balance += deposit;
 }// end deposit
/** Process a withdrawal
 * @param withdrawal the amount withdrawn
 */
 public void withdraw(double withdrawal) {
 balance -= withdrawal;
 }// end withdraw 
}// end BankAccount

In a main class we could have the following statements to make use of or test the BankAccount class.

// Construct a new BankAccount object and assign it's reference to myAccount

BankAccount myAccount = new BankAccount("123456789");

// Construct a new BankAccount object and assign it's reference to yourAccount

BankAccount yourAccount = new BankAccount("373737373");

// deposit 2000 into myAccount. Methods are called using the . notation

myAccount.deposit(2000);

// deposit 100 into your account

yourAccount.deposit(100);


Now consider the Student class description.

In a main class we could have the following statements to make use of the Student class.

// Construct a new Student object and assign it's reference to me

Student me = new Student(''Kraynek'',''37'');

//Construct a new Student object and assign it's reference to aStudent

Student aStudent = new Student(someName,someID);

// add Calculus to me's schedule and drop TechnicalWriting from aStudent's schedule

me.add(''Calculus'',4);

aStudent.drop(''TechnicalWriting'');



In order to input information from users we use the JOptionPane method showInputDialog(String prompt) In either case the input is retrieved as a String object. The pattern for this is:

String input = JOptionPane.showInputDialog("a Prompt for the user");
if( input == null ) break; OR return; OR System.exit(0);

If the user clicks cancel then null is assigned to input so there is no input. Otherwise the the input String may have different types of information ( words and/or numbers). The scanner class is used to extract the information. This is done as:

Scanner myScanner = new Scanner(input);

Now the Scanner methods

String next(), int nextInt(), double nextDouble(), and boolean hasNext() can be used to "get" the next token in the String input.

See ScannerIntsExample.java


Many times the String objectSelection is done using the if and if/else statements. The if statement syntax is

if( boolean-expression ) {

.....

} // end if

and

if( boolean-expression ) {

...

} else {

...

} // end if

Examples:

if( x == 37 ) {

JOptionPane.showMessageDialog(null,"x = " + 37);

} // end if

if ( word.equals( "Texas" ) {

JOptionPane.showMessageDialog(null, word + "equals Texas");

} else {

JOptionPane.showMessageDialog(null,word + "does not equal Texas");

} // end if



Repition can be done using the while statement. A while loop pattern is:

while( true ) {

...

if( boolean-expression ) break;

...

} // end while


The semantics are: The ... statements are executed (if any), if the boolean-expression is true the next statements that are executed are the ones immediately after the end while, otherwise the ... statements are executed and then back to the while statement and so on.

Examples:

int n = 33;

String out = "";

while( true ) {

if( n <= 1 ) break;

out += n + "\n";

n = n / 2;

} // end while
JOptionPane.showMesageDialog(null,out);
This segment will display is the JOptionPaneWindow:

33

16

8

4

2

int index =0;

String s = someString;

while( true ) {

int commaIndex = s.indexOf(",");

if( commaIndex == -1 ) break;

s = s.substring(0,commaIndex) + s.substring(commaIndex+1);

} //end while


This segment removes all occurrences of "," (a comma) from someString.


A pattern to accumulate strings in a String variable is: (the name of the String variable can be any name)

String out = "";

...

while( true ) {

...

out += someString;

...

} // end while

Similarly a pattern to accumulate numbers (ints) is an int variable is: (the int variable cane be any name)


int sum = 0;

while( true ) {

...

sum += someNumber;

...

} // end while

See ScannerIntsExampleLoop.java , ScannerExample.java , NumberOperationsExample.java and LabExerciseThree.java.


If the output is large then we can use the JTextArea pattern:

String out = "":
// accumulate all of the output in out
JTextArea outArea = new JTextArea(numRows, numColumns);
outArea.setText(out);
JOptionPane.showMessageDialog(null.new JScrollPane(outArea);

//The JScrollPane class will put scroll bars around the JTextArea if necessary.

//The font of the JTextArea can be set by the satetment:

outArea.setFont(new Font("some font",Font.BOLD,20);

//where Font.BOLD can be Font.ITALIC or Font.PLAIN and 20 is the font size.


See JTextAreaExample.java.



The NumberFormat class can provide a method to format numbers or currency using a standard format.
The DecimalFormat can specify a user defined format for numbers.

See FormatExample.java and LabExcerciseFour.java.

A static member of a class (for example a field or method) is on that is shared by all objects of the class. A static member can (and should) be referenced by the class name. Since there is only one static member for all objects of the class to share and each object has their own version of non-static members of the class a non-static member cannot be referenced by a static one. The static member would not know which version of the non-static one to choose.

The
Scanner class can be used to read strings, ints and doubles from files (and to extract them from strings). Some methods of the Scanner class are:

boolean hasNext()

String next()

int nextInt()

double nextDouble()

String nextLine()

The default delimiters used by the Scanner class are whitespace.

See Scanner Example one, Scanner Example 2 and Example 3.

For using the Scanner class to read from a file see Scanner Text File Example , Scanner Text File with JTextArea IO , Two Scanners Text File Example One (Use the data file numbers.txt) , and Two Scanners text File Example Two (Use the data file numbers2.txt)


The methods

void useDelimiters(String pattern)

can change the delimiters from the default delimiters ones specified by the String pattern. Some examples are

"[c]" use the character c as the delimiter where c is any character

"[c]+" use any number of c's as the delimiters

"[c1c2...ck]" use any of the characters ci's as delimiters

"[c1c2...ck]+" use any of the characters ci's any number of times as delimiters

"[^c1c2...ck]" use any of the characters except ci's as delimiters

0-9 represents the range of digits 0-9

a-z represents the range of letters a-z


For example

"[:]" would use a single : as the delimiter

"[ ]+" would use any number of blanks as delimiter

"[^0-9]+" would use and number of non-digits as delimiters

"[^a-zA-Z]+" would use any number of non-letters as delimiters

"[:0-9\n]+" would use any number of :'s digits and/or the end of lines as delimiters


The Wrapper classes are classes that have a primitive type as the data field. For example Integer and Double. Some methods are:

Constructor from and int/double

int intValue()

double doubleValue()


Given an int variable x then the operation new Integer(x) is called boxing the int variable x.

Given an Integer variable y the the operation y.intValue() is called unboxing the Integer variable y.

Similarly given a Double variable z the operation z. doubleValue() is called unboxing the Double variable z.


Java 5 has autoboxing and auto unboxing. This means that an int variable is boxed whenever the context would indicate it makes sense to do so. For example in the following the ints are automatically boxed and the Integers are automatically unboxed>

Integer z = 37;

int x = 111;

z = x;

int a = z;

x = z;

See WrapperExample.java for an example.


The ArrayList<AnyClass> class is a class whose object hold collections of objects of AnyClass. For example ArrayList<String> would hold Strings, ArrayList<Integer> would hold Integers and ArrayList<BankAccount> would hold BankAccount objects. Objects are added to an ArrayList object at the end of the list much like concatenating a character at the end of a String. Similar to a String's characters, an ArrayList's objects have an index starting at 0. The first object has index 0 , the second has index 1 etc. Some ArrayList<T> (where T is any class) methods are:

boolean add(T x); (return true always)

int size();

T get(int index);

int indexOf(T x); (returns -1if x is not in the ArrayList)

boolean remove(T x); (returns false if x is not on the ArrayList; true otherwise)

T set(int index, T x); change the value at the index to x;

void add(int index, T x); insert x and index and move all others up one.

void remove(int index); remove the object at index and move others down one.

The ArrayList object is automatically adjusted when something is added or removed.


The objects in an ArrayList<T> variable elements can be processed using a for each loop or a counter-countered for loop.

The for each loop has syntax:

for( T x : elements) {

// each time thru the loop x takes on the next object from the ArrayList<T> elements

} // end for

The variable x can be read or written. If it's value is changed the corresponding value in the ArrayList is NOT changed.

A typical counter-controlled for loop looks like:

for( int i = 0; i < elements.size(); i++ ) {

// not the elements can be accessed using elements.get(i), elements.add(i, something), etc.

} // end for

See ArrayList Example 1 , ArrayList Example 2 , ArrayList Example 3 , ArrayList of Integer Example and ArrayList ForEach Example .


In order to have a GUI interface with buttons use the JFrame, JPanel, JLabel and JButton classes. The code that is executed when a button is clicked must be put a class that implements the ActionListener interface. An interface is a like a class with only unimplemented methods. The ActionListener interface has one unimplemented method. That method is void actionPerformed(ActionEvent e). So the code that is executed when a button is clicked will be the code in the actionPerformed method. The pattern is:

class SomeAction implements ActionListener {

public void actionPerformed(ActionEvent e) {

// the code goes here

}

}

An object of this class is associated with a JButton object using the addActionListener method of the JButton class. An anonymous object of the SomeAction class is typically used as in the statement:

aButton.addActionListener(new SomeAction());

See JButtonsExample for an example.


A class in Java extend another class. When a class extends another class all of the public fields and methods of the class that is being extended are available in the extended class. The concept of extending a class in called inheritance.


Sometimes it is useful to extend the JPanel class to design your own panel class that contains a button. See JButtonsExamplePanelExtension for an example extending JPanel.


Every class in Java automatically extends the (super) class Object. Two important methods of the class Object are:

boolean equals(Object x);

String toString();


The scope of a name (variable name, class name etc) is where the name can be accessed. In Java the scope of a name is the area between the {..}'s where the name is defined.


When designing a class in Java the things to consider are:


The syntax of a method is

return-type methodName(parameter(s))

where return-type is void, any class or any primitive type. If the return-type is any class or any primitive type then a value of the corresponding must be returned using the return statement. If the return-type is void then no value is returned so use the return statement without a value or use the end of the method.


Parameters in a method look like variable declaration statements, i.e. type variableName. Each parameter is a local variable to the method and when the method is called the parameters are initialized to the value of the calling parameters. This means the value of the calling parameter is copied into the local variable parameter. This is called passing the parameters by value. For primitive types this means that a value is copied to the local variable parameter and therefore the calling parameter cannot have it's value changed. For class type this means that a reference to a class object is copied to the local variable parameter and therefore the calling parameter cannot have it's value changed either and will still refer to the same object regardless what is done to the corresponding local variable parameter. However if the class it refers to has modifier methods then field values of the object can be changed. See IndexOfAndSortExample for examples.


When writing a non-static method sometimes it is necessary to refer to the object that will be calling the method after an object of the class is constructed. A reference to that object is the the keyword this.


It was mentioned above that the super class Object have the method boolean equals(Object x) and since all classes extend the class Object all classes also have an equals method. This is because any two objects can be compared for equality regardless of their type. The equality test in class Object is do the two object being compared refer to the same object. When designing a class there may be a natural and more useful way to test for equality. For example the String class compares the two String character by character and the Integer class test whether the int values are the same. The equality test for BankAccount object was to check to see if the id's were the same. If there is a way to compare two object of a class to see if one was smaller than the other then in order to be able to do it in a consistent way (for example in a sort method to sort any ArrayList of objects) an interface is used. A method to compare for less than cannot be in the super class Object since an arbitrary pair of objects cannot be compared for less than. Which is smaller, an apple or an orange? So the interface Comparable<T> is used. This interface has one method, public int compareTo(T x) and returns a negative int value if the caller is less that the parameter, 0 if they are equal and a positive int value if the caller is greater than the parameter. To design a class so that it's objects can be compared for less than do:

public class SomeClass implements Comparable<SomeClass> {

..................................

all other methods of the class

public int compareTo(SomeClass x) {

code to compared

}// end compareTo

}// end SomeClass


For example

public class BankAccount implements Comparable<BankAccount> {

....................................

all other methods of BankAccount

public int compareTo(BankAccount account) {

return id.compareTo(account.id);

}// end compareTo

} // end BankAccount

will compare BankAccount objects for less than using the String compareTo method i.e. in alphabetic order using the id field.



The three important ideas of Object Oriented Programming are :



As we saw in the CountWordsExerciseSolution using parallel ArrayLists is one way to keep related data together. The Collections class is an utility class with many useful static methods. One of them is a method to sort an ArrayList<T> object. So suppose we have the declarations (as in the CountWordsExercise) :


ArrayList<String> words = new ArrayList<String>();

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


then Collections.sort(words) will sort the words ArrayList and Collections.sort(counts) would sort the counts ArrayList. Using parallel ArrayLists is a problem since sorting the words will not keep the corresponding counts in the proper order and vice versa. A much better way to do this is to design a class ,say Word, that has two data fields, a String for the word and an int for the corresponding count. This is covered in Assignment One. So if we have ArrayList<Word> wordList then we can now call Collections.sort(lwordList) to sort the words and keep track of the counts.

But how does the Collections sort method compare for less than? The sort method must know the name of the method for less than comparison for String, Integer and Word objects. How? The idea is to agree on a name. This was the idea behind the equals method. Since the equals method is automatically included in every class and each class can define the equals method for themselves then other methods like the contains method of the ArrayList<T> class can use the equals method to compare pairs of T objects for equality where T could be any class. But not every class can compare it's objects for less than in a meaningful way. So a compare method is not included in every class. In order to have a common way to compare for less than for those classes where it makes sense an interface is used.

An interface is a collection of unimplemented methods. So an interface is a list of return-type followed by a method signature ( the signature of a method is it's name and the types and order of it's parameters). So an interface looks something like:


public interface InterfaceName {

return-Type1 method1(parameters);

return-Type2 method2(parameters);

etc.

} // end interface


Interfaces are used for (i) data abstraction and (ii) passing methods to methods. The three important Object Oriented Programming concepts are

Data Abstraction (encapsulation and information/implementation hiding)

Inheritance and

Polymorphism.

The Java interfaces Comparable<T> and Comparator<T> illustrate the two uses of interfaces.

The Comparable<T> interface is defined in Java as:

public interface Comparable<T> {

public int compareTo(T rhs);

}//end interface


When the compareTo method is implemented by a class the meaning is as follows;

if this is less than rhs then the method returns a negative int value

if this is equal to rhs then the method returns a 0

if this is greater than rhs then the method returns a positive int value


So when the Collections sort method is called to sort an ArrayList<T> then the sort method assumes that class T has implemented the Comparable<T> interface so it uses the compareTo method for less than comparisons. The Comparable<T> interface is always implemented as part of another class. It is the agreed upon method to do less than comparisons. So if a class T has a natural way to compare it's objects for less than T should implement the Comparable<T> interface. See the Person and BankAccount classes.


Now suppose we want to sort the objects from a class T that does not implement the Comparable<T> interface (no natural order of the objects) or we want to sort the objects in an order different than the natural order. We need to pass a compare method to the sort method. But how? Only primitive types or class type objects can be passed to a method. So we pass an object from a class with no data and only one method. That method is the method to compare objects of class T.


The Comparator<T> interface is defined in Java as:

public interface Comparator<T> {

public int compare(T lhs, T rhs);

}

The Comparator<T> interfaced is always implemented in a class by itself. So we do the following:

class MyTCompare implements Comparator<T> {

public int compare(T lhs, T rhs) {

//code to do compare

......................................

}

}

We pass an object of this class to the sort method as:


Collections.sort(myArrayList, new MyTCompare() );


or


Comparator<T> myTCompare = new MyTCompare() );

Collections.sort(myArrayList,myTCompare);