Session 2: 25 March: Chapter 5: Lists, Logic and Loops

The chapter talks about Lists Logic and Loops but I have also added Strings since they are very important.

Strings

class java.lang.String: an object which represents a string of characters. A string is a genuine object, not an array of characters as in other languages.

in Java, characters are double-byte unicode not single-byte ascii

Most (all?) world languages natively supported

A big improvement from earlier languages

unicode.org if you want more information

Strings are invariant objects: once created they can't be changed.

Any time your program needs to change a string it will actually create a new string. Often you will then throw the throw the original string away.

example: s = s.trim(); //same variable used, original s is destroyed.

Several different ways to create Strings in your program, for example:

using a String literal

String s = "Obi-Wan";

No other Java object can be created this way: strings are special.

by concatenating other strings

String s = "Anakin " + "Skywalker";

Actually this statement creates three strings but throws two of them away.

from the toString() method of any object (derived from java.lang.Object)

s = anyObject.toString();

Object has a default implementation of toString() which you might override in your class to get a more meaningful result.

Reading from a file or network socket

Comparing Strings:

Can't necessarily use == because that is testing for object identity. It might work in some cases but not in others-- don't rely on it.

Use equals(). Also equalsIgnoreCase()

Can also use intern(): if s1.equals(s2) then s1.intern() == s2.intern(). Canonicalizes the string. Returns a new object.

compareTo() compares them lexicographically (for alphabetizing)

indexOf() finds a substring or character

length() and substring()

Other useful classes from the Java API:

java.lang.StringBuffer for building up documents such as HTML from individual strings.

java.util.StringTokenizer for parsing an input string into individual words or tokens.

java.io.StringReader for converting a string into a stream of characters (like reading a file).

Arrays

an array is a special type of object

a fixed-length set of elements that can be accessed by index.

The elements are always either primitives or object references, depending on the array type. They are never actual objects (unlike C++).

declaring

primitive: int i[] = new i[100];

object: Foo f[] = new Foo[100];

creating

values initialized to 0, false or null

explain what null is

null String different from empty String

One-line creation

char[] tgif = { 't','g','i','f' }

getting the size: length

assigning and accessing elements

arrays are always 0-based: first element is always 0, last is always length - 1

right: x[0] for first element

wrong: x[x.length] for last element. Use x[x.length - 1].

This is the case for almost all programming languages

accessing an element

int ii = i[0];

replacing one element with another

i[0]=1; i[0]=2;

f[0]= new Foo(0); f[0] = new Foo(1);

copying elements

to copy: x[1] = x[0];

array elements object reference

f[1] = f[0]: how many references do I now have? How many objects?

f[0] = new Foo(0); f[1] = new Foo(0); how many objects?

f[1] = f[0]; f[0] = null; what happened?

f[0] = new Foo(); f[0] = null; what happened to the object?

changing the state of an object element without replacing it

x[0] = new Foo(); x[0].setName("luke");

String arrays

Remember strings are objects, not primitives, even though they sometimes act like primitives.

String[] s = new String[10] is initialized with 10 nulls, not 10 empty Strings.

s[0]="jedi" creates one String object and stores its reference in the array.

Remember that most string operations create a new string object, so

s[0] = "hello " + "dolly"; how many Strings are creating in executing this expression? What is stored in the array?

Arrays are strongly typed

Can't mix different types in one array

Wrong: int i[] = new int[10]; i[0]=1; i[2]=false;

Wrong: String s[] = new String[10]; s[0]="wookie"; s[1]= new Foo()

Exception: declare array using common superclass

Object[] o = new Object[10]; o[0]="ewok"; o[1]=new Foo();

Reading from such an array you must use a cast to get back the original type:

String s = (String)o[0]

Foo f = (Foo)o[1]

arrays of arrays

equivalent to multidimensional arrays

String[][] s = new String[10][2]; s[0][0] = "jabba";

Use for grids of information, e.g. data imported from a spreadsheet.

resizing an array

System.arraycopy(): will copy array elements into a new array

java.lang.Vector: an object that acts like a resizable array (actually uses arraycopy internally to allocate bigger arrays).

Vector is very useful for cases where you don't know in advance how large the array will get.

Example: caching data read in from a database, where you don't know in advance how many searches will be done.

conditionals

the if keyword is called a conditional. It always evaluates a boolean expression.

Usually after an if you use curly brackets to denote a block of code. I use these even if there's just one line.

if (i == 0) { /*do something*/ }

if (b == true) can be shortened to "if (b)".

if (b == false) can be shortened to if (!b)"

wrong: if ("true"). That's a string which is an object, you can't evaluate an object as a boolean. However, 'if (s.equals("true"))' is OK.

beware of 'if (s == "true")'. Unless you have intern()d the string it will always return false even if the strings are equivalent.

"if (true)" will always execute. "if (false)" will never execute.

else

The if may or may not terminate with an else.

if (b) { /*something*/ } else { /*something else*/ }

else if

if (i == 0) { /*something*/ } else if (i == 1) { /*something else*/ } else { /*something other*/ }

switch

is an abbreviated form of "if - else if - else".

Only applies to ordinal primitive types: including int, long, byte, char. Can't use with strings or other object types. Can't use with float or double.

switch (i) { case 0: i=i+1; break; case 1: i=i-1; break; default: i=0; }

if you leave out the break it will "fall through" to the next one. A common source of errors.

book example (DayCounter)

for

used to repeat something a definite number of times

first expression evaluated once at beginning

second expression evaluated at the beginning of each iteration

third expression evaluated at the end of each iteration

for (int i=0; i<10; i++) { } How many times will it repeat?

How about this one: for (int i=1; i<=10; i++) { }

You can also count backwards: for (int i=9; i>=0; i--) { }

Often used with an array to iterate over all elements:

for (int i=0; i<arr.length; i++) { if (arr[i]==0) { /*something*/ } }

Don't change the counter within the loop - that's asking for trouble.

An infinite loop: this is OK as long as you have a break somewhere inside the body. Otherwise it will hang your program.

for (;;) { ... if (b) break; ... }

Nested for loops: OK as long as you use a different counter (give example).

Common mistake: put a ; at the end of the for statement: if (i=0; i<10; i++); This is a null body loop.

Note scope: if I declare i within the loop statement, it will only be visible in the loop, not afterwards. If I declare i before the loop, it will still be visible after the loop.

while and do

used to repeat something an indefinite number of times - termination is determined by something inside the loop

while

The condition test is before the loop body:

while (b) { /*something*/ }

can use break for early termination

infinite loop: "while (true)" is OK if you have a break.

do

The condition test is after the loop body

Less commonly used -- usually there is some initial condition which needs to be checked

do { } while (b);

"do until" can be done with "do while (!b)"

book example (CopyArrayWhile)

break and continue

Can be used with any loop

continue "skips" the remaining part of the loop body. Can be used in place of an "if" block.

break "breaks out" of the loop immediately.

In a nested loop, break only breaks out of the inner loop.