395 lines
10 KiB
Markdown
395 lines
10 KiB
Markdown
|
# Lesson 3: Fundamental Programming Structures in Java
|
||
|
|
||
|
## 3.1 Write a simple Java program
|
||
|
|
||
|
```java
|
||
|
public class FirstSample
|
||
|
{
|
||
|
public static void main(Sting[] args)
|
||
|
{
|
||
|
System.out.println("We will not use 'Hello, World!'")S
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
* Java is case sensitive: `Main` is not `main`
|
||
|
* Keywords `public`, `static`, etc.
|
||
|
* Braces `{}` are used for blocks
|
||
|
* Statements end in semicolons `;`
|
||
|
* Everything is inside a class. (i.e. everything is class). Creating second class is similar.
|
||
|
* By convention, class names are *CamelCase*
|
||
|
* Source file must be called `FirstSample.java`
|
||
|
|
||
|
* `System.out.println(<str>);`
|
||
|
* `System.out.` is an object
|
||
|
* `println` is an method of `System.out`
|
||
|
* General structure: `object.method(parameters)`
|
||
|
* Parentheses needed even if there are no parameters: `System.out.println();`
|
||
|
|
||
|
Comment in Java
|
||
|
|
||
|
* Single line: `//`
|
||
|
* Multiple line: `/* new line */`
|
||
|
* Documentation comments: `/** documentation lines */`
|
||
|
* comments does not nest
|
||
|
|
||
|
## 3.2 Work with numeric data type
|
||
|
|
||
|
### Data Type
|
||
|
|
||
|
#### Integer
|
||
|
|
||
|
Four Integer types
|
||
|
|
||
|
| Type | byte number | description |
|
||
|
| ------- | ----------- | ------------------------------- |
|
||
|
| `int` | 4 | -2,147,483,648 to 2,147,483,648 |
|
||
|
| `short` | 2 | -32,768 to 32,768 |
|
||
|
| `long` | 8 | |
|
||
|
| `byte` | 1 | |
|
||
|
|
||
|
When writing number, there are **Number Literals**
|
||
|
|
||
|
* Long: `400000000L`
|
||
|
* Hex: `0xCAFE`
|
||
|
* Binary: `0b1111_0100` use `_` to s
|
||
|
|
||
|
#### Floating type
|
||
|
|
||
|
Two Floating types:
|
||
|
|
||
|
| Type | byte number | Description |
|
||
|
| -------- | ----------- | ----------- |
|
||
|
| `float` | 4 | |
|
||
|
| `double` | 8 | |
|
||
|
|
||
|
Floating Literal:
|
||
|
|
||
|
* float literals: `0.5F`
|
||
|
* Only use `float` if a library requires it
|
||
|
* Special values `Double.POSITIVE_INFINITY`, `Double.DEGATIVE_INFINITY`, `Double.NaN`
|
||
|
|
||
|
#### `char` Type
|
||
|
|
||
|
* Originally used to describe Unicode char with UTF-8 encoding. But now unicode has grow to UTF-16. So, every unicode char requires 1 or 2 char:
|
||
|
* e.g. "U+1D546"
|
||
|
* Avoid `char` unless you know what it is
|
||
|
* Char literal enclosed in single quotes. e.g. `'A'`
|
||
|
* Special unicode. e.g. `\n`, or `\u2122` (for trade mark symble)
|
||
|
|
||
|
#### Bool Type
|
||
|
|
||
|
* 2 values: `false`, `true`.
|
||
|
* No conversion btw `int` and `boolean`
|
||
|
|
||
|
Totally Java has 8 primitive types:
|
||
|
|
||
|
* `int`, `long`, `short`, `byte`
|
||
|
* `double`, `float`
|
||
|
* `char`
|
||
|
* `boolean`
|
||
|
|
||
|
### Variable
|
||
|
|
||
|
* Java is strongly typed language. Every variable must be declared with type (like C, C++): `int VacationDays`
|
||
|
* Initialization is optional: `int vacationDays = 12;`
|
||
|
* Declaration can happen everywhere, recommanded to be declare along first use
|
||
|
* Can assign new value with `=` operator
|
||
|
* **Constant** declared with `final`: `final int vacationDays = 12;`
|
||
|
|
||
|
### Math Operations & Functions
|
||
|
|
||
|
* Arithmetic: `+`, `-`, `*`, `/`
|
||
|
* Integer division and modulus: `/` and `%`
|
||
|
* Using function from Math class:
|
||
|
* `Math.sqrt(x)` for square root
|
||
|
* `Math.pow(a,b)` a power of b
|
||
|
* `Math.floorMod(a,b)` like `a%b`
|
||
|
* Trig and log functions: `Math.sin()`
|
||
|
|
||
|
Conversion between types are possible, as long as they don't loss information. Otherwise explicit convert use **casts** e.g.:
|
||
|
|
||
|
```java
|
||
|
double x = 9.997;
|
||
|
int nx = (int) x;
|
||
|
int rx = (int) Math.round(x)
|
||
|
```
|
||
|
|
||
|
### More Operations
|
||
|
|
||
|
* Combining assignment with operators: `n+=4`
|
||
|
* `-=`, `*=`, `/=`, `%=`
|
||
|
* Increment, decrement: `n++`, `n--`
|
||
|
* Relational operators: `==`, `!=`, `<`, `<=`, `>`, `>=`
|
||
|
* Boolean operators: `&&`, `||`, `!`
|
||
|
* Bitwise operators: `&`, `|`, `^`, `>>`, `>>>`, `<<`
|
||
|
* Conditional operator: `x<y ? x:y`, if true, then x; if false, then y
|
||
|
|
||
|
### Enumerated (枚举) Types
|
||
|
|
||
|
* A type with restricted set of values. e.g. `enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE}`
|
||
|
* Can declare variable of this type: `Size z = Size.MEDIUM`
|
||
|
* Variable of type `s` can only hold size values or `null`; So much safer for coding
|
||
|
|
||
|
### Java 9 New Feature: JShell Tips
|
||
|
|
||
|
* `Shift+Tab, V` fills in variable declaration
|
||
|
* `Shift+Tab, I` fills in import declaration
|
||
|
|
||
|
### Java 10 New Feature: Local Type Interference
|
||
|
|
||
|
* Can use `var` instead of type for local variable: `var counter = 0;`
|
||
|
* Still strongly types: `counter = 0.5;` will lead to error as can't assign a double to int
|
||
|
* Useful for unwieldy (complicated) type names: `var traces = Thread.getAllStackTraces(); // a Map<Thread,StackTraceElement[]>`
|
||
|
|
||
|
## 3.3 Work with Strings and API documentation
|
||
|
|
||
|
### String Manipulation
|
||
|
|
||
|
* String = a sequence of Unicode characters.
|
||
|
* Enclosed in double quotes: `"Java\u2122"
|
||
|
* It's instance of `String` class
|
||
|
|
||
|
#### Substring
|
||
|
|
||
|
* Use `substring` method to extract substrings
|
||
|
* Position start at zero: 0,1,2,3...
|
||
|
* Last position is excluded: exclude 3rd char
|
||
|
* Position are code units
|
||
|
|
||
|
```Java
|
||
|
String gretting = "Hello"
|
||
|
String s = greeting.substring(0,3); // return "Hel"
|
||
|
```
|
||
|
|
||
|
#### String Concatenation
|
||
|
|
||
|
* Concatenation (+) joins strings
|
||
|
* If one operand is not a string (e.g. int), it's cast to string characters
|
||
|
|
||
|
```java
|
||
|
String expletive = "Expletive";
|
||
|
String PG13 = "deleted";
|
||
|
String message = expletive + PG13;
|
||
|
```
|
||
|
|
||
|
#### More about Strings
|
||
|
|
||
|
* String are immutable: `greeting.substring(0,3)` or `greeting + "!"` does not change `greeting`. As the object itself is not changed, it only return a new object
|
||
|
* Can be reassigned: `greeting = greeting.substring(0,3)`
|
||
|
* String comparison: `"Hello".equals(greeting)` or `"Hello".equalsIgnoreCase(greeting)`
|
||
|
* Don't use `==`: because `==` check whether it point to a same memory
|
||
|
* Empty string "" has length `0`
|
||
|
* `null` indicates no string at all.
|
||
|
|
||
|
#### Code Points and Code Units
|
||
|
|
||
|
* `s.length()` = number of code units (not Unicode characters)
|
||
|
* `s.charAt(i)` = ith code unit
|
||
|
* Slice string to get ith code point:
|
||
|
|
||
|
```java
|
||
|
int index = s.offsetByCodePoints(0,i);
|
||
|
int cp = s.codePointAt(index);
|
||
|
```
|
||
|
|
||
|
* To get all code points: `int[] codePoints = str.codePoints().toArray();`
|
||
|
|
||
|
|
||
|
#### String API
|
||
|
|
||
|
* There are many useful `String` methods
|
||
|
* `trim` yield a new string
|
||
|
* `toLowerCase`
|
||
|
* etc.
|
||
|
|
||
|
## 3.4 Write programs that read input & produce output
|
||
|
|
||
|
### Terminal input
|
||
|
|
||
|
* Read console input from a `Scanner`
|
||
|
* `System.in` by itself used as system console, but cannot read in
|
||
|
|
||
|
```java
|
||
|
Scanner in = new Scanner(System.in);
|
||
|
```
|
||
|
|
||
|
* `Scanner` object has methods `nextLine`, `next`, `nextInt`, `nextDouble` to read input:
|
||
|
|
||
|
```java
|
||
|
int age = in.nextInt();
|
||
|
```
|
||
|
|
||
|
* Need to add import statement:
|
||
|
|
||
|
```java
|
||
|
import java.util*
|
||
|
```
|
||
|
|
||
|
### Terminal output (formatted)
|
||
|
|
||
|
* Use `printf` for formatted printing:
|
||
|
* `f` for floating-point, `d` for integer, `s` for string, etc.
|
||
|
|
||
|
```java
|
||
|
System.out.printf("Price:%8.2f", 10000.0/3.0); // Print Price: 3333.33
|
||
|
```
|
||
|
|
||
|
Just for formatting string (not output)
|
||
|
|
||
|
```java
|
||
|
String message = String.format("Hello, %s. Next year, you'll be %d", name, age);
|
||
|
```
|
||
|
|
||
|
### Read/Write File
|
||
|
|
||
|
Same as terminal input/output. Just use object to deal with file
|
||
|
|
||
|
* Read from a file
|
||
|
|
||
|
```java
|
||
|
Scanner in = new Scanner(Paths.get("myfile.txt"), "UTF-8");
|
||
|
```
|
||
|
|
||
|
* Writing to a file using PrintWriter constructor
|
||
|
|
||
|
```java
|
||
|
Printwriter out = new PrintWriter("myfile.txt", "UTF-8");
|
||
|
out println(...);
|
||
|
```
|
||
|
|
||
|
* Require packages `import java.io, java.nio.path`
|
||
|
* Need to tag `main`, for compilation error catching
|
||
|
|
||
|
```java
|
||
|
public static void main(String[] args)
|
||
|
{
|
||
|
Scanner in = new Scanner(Paths.get("myfile.txt"), "UTF-8");
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## 3.5 Use the control flow constructs of the Java
|
||
|
|
||
|
* If statement.
|
||
|
* While statement: check condition first. e.g. [Retirement.java](Core_JAVA_Volume1/corejava/v1ch03/Retirement/Retirement.java)
|
||
|
* Do while statement: do before check condition. e.g. [Retirement2.java](Core_JAVA_Volume1/corejava/v1ch03/Retirement2/Retirement2.javas)
|
||
|
* For loop: e.g. [LotteryOdds.java](Core_JAVA_Volume1/corejava/v1ch03/LotteryOdds/LotteryOdds.java)
|
||
|
* Switch statement
|
||
|
* `break` statement;
|
||
|
* `continue` statement will skip remaining and jump to next iteration
|
||
|
|
||
|
|
||
|
Used to breaks out of a loop
|
||
|
|
||
|
```java
|
||
|
while (years <= 100)
|
||
|
{
|
||
|
balance += payment;
|
||
|
double interest = balance * interestRate / 100;
|
||
|
balance += interest;
|
||
|
if (balance >= goal)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
years++;
|
||
|
}
|
||
|
```
|
||
|
|
||
|
We can always replace `break` by placing remainder insider `if`
|
||
|
|
||
|
```java
|
||
|
while (years <=100 && balance < goal)
|
||
|
{
|
||
|
balance += payment;
|
||
|
double interest = balance * interestRate / 100;
|
||
|
balance += interest;
|
||
|
if (balance < goal)
|
||
|
years++
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## 3.6 Work with big numbers when arbitrary precision is required
|
||
|
|
||
|
* If precision of `int` or `double` not enough, use `BigInteger` or `BigDecimal`
|
||
|
* Turn an `int` into a `BigInteger`
|
||
|
```java
|
||
|
BigInteger a = BigInteger.valueOf(100000000);
|
||
|
```
|
||
|
* Use methods such as `add` and `multiply` to combine big numbers. You cannot use math operator on object
|
||
|
```java
|
||
|
BigInteger c = a.add(b);
|
||
|
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2)));
|
||
|
```
|
||
|
|
||
|
e.g. as shown in [BigIntegerTest.java](Core_JAVA_Volume1/corejava/v1ch03/BigIntegerTest/BigIntegerTest.java)
|
||
|
|
||
|
## 3.7 Use arrays to store multiple elements of same type
|
||
|
|
||
|
### Creating/Initialize Array
|
||
|
|
||
|
* Type of array of object: `type[]`. e.g. `int[]`
|
||
|
* Array variable declaration: `int[] a;`
|
||
|
* `new` operator need to create object: `int[] a = new int[100];`
|
||
|
* Array indexes are from `0` to `a.length-1`
|
||
|
* Use `[]` bracket to access elements: `a[i]`
|
||
|
|
||
|
```java
|
||
|
for (int i = 0; i < a.length; i++)
|
||
|
{
|
||
|
System.out.println(a[i]);
|
||
|
}
|
||
|
```
|
||
|
|
||
|
* Or use `for each` loop, e.g.
|
||
|
|
||
|
```java
|
||
|
for (int element : a)
|
||
|
{
|
||
|
System.out.println(element);
|
||
|
}
|
||
|
```
|
||
|
|
||
|
* Declare & Initialize array: `int[] smallPrimes = {2,3,5,7};`
|
||
|
* Anonymous arrays: `new int[] {17,19,23,29}`
|
||
|
|
||
|
### Copy Arrays
|
||
|
|
||
|
* Copying array like `int[] array1 = array2;` will not trully copy, it only copied reference. Hence both array variables are pointing toward same memory. Changing in one will result change in another
|
||
|
* True copy via `Arrays.copyOf(array, length)` method
|
||
|
|
||
|
e.g. as shown in [LotteryDrawing.java](Core_JAVA_Volume1/corejava/v1ch03/LotteryDrawing/LotteryDrawing.java)
|
||
|
|
||
|
### Multidimensional Arrays
|
||
|
|
||
|
* `int[][]` is an array of arrays or a 2-d dimensional array:
|
||
|
|
||
|
```java
|
||
|
int[][] magicSquare =
|
||
|
{
|
||
|
{16,3,2,13},
|
||
|
{5,10,11,8},
|
||
|
{9,6,7,12},
|
||
|
{4,15,14,1}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
* Without initializer:
|
||
|
|
||
|
```java
|
||
|
int[][] magicSquare = new int[ROWS][COLUMS];
|
||
|
```
|
||
|
|
||
|
* Access element: `magicSquare[1][2]`
|
||
|
* Use loop to traverse elements
|
||
|
|
||
|
```java
|
||
|
for (int[] row : magicSquare)
|
||
|
for (int element : row)
|
||
|
// do something
|
||
|
```
|
||
|
|
||
|
e.g. as shown in [CompoundInteres](Core_JAVA_Volume1/corejava/v1ch03/CompoundInterest/CompoundInterest.java)
|
||
|
|
||
|
**Ragged array** (each row does not has same number of elements) as shown in [LotteryArray.java](Core_JAVA_Volume1/corejava/v1ch03/LotteryArray/LotteryArray.java)
|
||
|
|