**More basics**
# Type inference
- We have been declaring the type of every variable at the same time
that we define it. It turns out for almost all the time we can
omit type declaration.
- For example, instead of writing `val n: Int = 3`,
we can simply write
```kotlin
val n = 3
```
- The Kotlin compiler has a builtin algorithm called
_type inference engine_ that can infer the type of the
variable being declared from the type of the expression
used to initialize it.
- You can still declare the type of a variable explicitly.
In that case the compiler checks that the declared type
agrees with the type of the initializing expresssion,
and gives an error message if they don't.
# Arrays
- Arrays is an _aggregate type_. An array is made up of pieces
of data of the same type called _elements_.
The type of elements is called the _base type_.
If B is a base type, the type "array of B" is written
in Kotlin as `Array`.
- For example, we can have `Array`, `Array>`, etc.
Thus, array types allow us to construct an infinite number
of new types.
- If an array has $n$ elements, the elements are indexed
using the nonnegative integers from $0$ to $n-1$.
- We can access and modify an individual element
through its index using the [] notation, e.g.,
`a[3]` is the element of `a` at index 3.
- The (references to) array elements are located at consecutive
memory locations.
- The reason arrays is an efficient data structure for keeping
bunches of things together is because we can get at
each individual element quickly by doing arithmetic
on its index.
# Arrays of primitive types
- Arrays of primitive types are efficient running-time-wise
and memory-wise.
You should try to use it if you care about efficiency.
- The names of arrays of primitive types are
+ `BooleanArray`
+ `CharArray`
+ `ByteArray`
+ `ShortArray`
+ `IntArray`
+ `LongArray`
+ `FloatArray`
+ `DoubleArray`
# Constructing primitive arrays
- Kotlin does not provide a way to write array literals.
The only way to create a new array is by calling
some special function.
Here are example declarations of arrays of primitive types:
```kotlin
val a1 = IntArray(5)
val a2 = intArrayOf(3, 5, 2)
```
The first statement declares the variable `a1` to be an `IntArray`,
creates an array of 5 `Int`s, initializes all elements to zero,
then makes `a1` point to the beginning of this array.
The second statement declares the variable `a2` to be an `IntArray`,
creates an array of 3 elements, initializes the 0th element to 3,
the 1st element to 5, and the 2nd element to 2,
then makes `a2` point to the beginning of this array.
- You will learn later that `IntArray(5)` is calling
an _array constructor_ while `intArrayOf(3, 5, 2)` is calling
a _factory function_.
# Constructing primitive arrays, continued
- In a similar manner, you have constructors
+ `BooleanArray(n)` for constructing a `BooleanArray` of size n
and initializing all elements to `false`
+ `ByteArray(n)` for constructing a `ByteArray` of size n
and initializing all elements to `0`
+ `ShortArray(n)` for constructing a `ShortArray` of size n
and initializing all elements to `0`
+ `LongArray(n)` for constructing a `LongArray` of size n
and initializing all elements to `0`
+ `FloatArray(n)` for constructing a `FloatArray` of size n
and initializing all elements to `0.0F`
+ `DoubleArray(n)` for constructing a `DoubleArray` of size n
and initializing all elements to `0.0`
- You also have factory functions `booleanArrayOf(...)`,
`byteArrayOf(...)`, `shortArrayOf(...)`,
`longArrayOf(...)`, `floatArrayOf(...)`,
and `doubleArrayOf(...)`
for creating and initializing arrays of the other primitive types
to the values you provide as arguments.
# Reading and modifying array elements
- Here is an example of performing various operations on arrays.
```kotlin
val a = intArrayOf(0, 1, 2, 3, 4)
println("originally a = ${a.joinToString()}")
for (i in 0 until a.size)
a[i] *= a[i]
println("after the for loop, a is now = ${a.joinToString()}")
val b = a
println("originally b = ${b.joinToString()}")
b[0] = b[2] - b[1]
println("after modifying b[0], b = ${b.joinToString()}")
println("and a = ${a.joinToString()}")
```
- Executing the code gives this output
```
originally a = 0, 1, 2, 3, 4
after the for loop, a is now = 0, 1, 4, 9, 16
originally b = 0, 1, 4, 9, 16
after modifying b[0], b = 3, 1, 4, 9, 16
and a = 3, 1, 4, 9, 16
```
# Arrays is a mutable, reference type
- A data object that allows changes to be made to its value
is said to be _mutable_.
(To _mutate_ means to change.)
A data object that does not allow changes to be made to its value
is said to be _immutable_.
The last piece of code snippet taught us that arrays are mutable.
- Except for primitive types, all Kotlin types are _reference types_.
The data itself is kept within an _object_,
and the variable only keeps a reference to the location of the object.
Objects are created during runtime.
- When we execute the code snippet
```kotlin
val b = a
```
where a, b are variables of the same reference type,
the variable `b` is made to point to the same object that `a`
is pointing to.
Modifying the content that `b` points to will change the
content that `a` points to as well since they are the same!
- The lesson here is that being a `val` variable does not mean
the data itself is immutable. It just means that you can't
change that variable to make it reference something else.
# Iterating an array
- Arrays are iterable, so you can use the `for` loop to walk
through them to perform some task on their elements without
having to refer to their indexes at all.
- For example, you can print all the elements by
```kotlin
val a = intArrayOf(1, 2, 3)
for (e in a)
println(e)
```
- If you also want the indexes, you can write
```kotlin
for ((i, e) in a.withIndex())
println("$i: $e")
```
instead of the usual
```kotlin
for (i in 0 until a.size)
println("$i: ${a[i]}")
```
# Characters and strings
- A `String` value is essentially a sequence of `Char` values.
- Even though `String` is not a primitive type, it is so
heavily used that Kotlin provides literals for it like
for the primitive types.
It also has the concatenation operator `+` that returns another
string that results from appending the second string to the
first.
- `String` is an immutable type. You can't change its data.
- But you can access the individual characters of a string
using the indexing operator [], exactly like the arrays.
- The String type differs from the array type in that
strings don't have a `size` property;
it has a `length` property instead.
- You can iterate through strings just like arrays.
# Strings, continued
- Here is some code that manipulates strings.
```kotlin
val message = "Hello"
println(message + " World")
println(message.length)
for (c in message)
println(c)
for (i in 0 until message.length)
println(message[i])
for ((i, c) in message.withIndex())
println("$i: ${message[i]}")
```
- Strings can be compared using these operators as well:
```kotlin
== != < <= > >= in !in
```
Comparison is done in dictionary order.
# Escape sequences
- The `Char` data represents 16-bit Unicode characters.
The Unicode characters are supposed to represent all
the symbols used in all languages in the world,
whether the language is alphabet-based or not, and then some.
However, some Unicode characters are either not printable or
not easy to see when printed;
Kotlin provides a special notation called _escape sequences_
for writing these characters.
- These are the escape sequences and their meanings:
```
Escape Sequence Represented Character
\t Tab
\b Backspace
\n Newline
\r Carriage Return
\' Single Quotation Mark
\" Double Quotation Mark
\\ Backslash
\$ Dollar sign
```
- You can also write any Unicode character using the escape sequence
syntax like '\\uFF00'.
# Raw strings
- A regular Kotlin string literal can contain escape sequences.
However, literals containing many escaped characters
can be hard to read,
so Kotlin provides another way to write string literals.
- A _raw string_ does not understand escape sequences.
Instead of using just one quotation mark `"` to enclose a string,
a raw string uses three quotation marks `"""` like this:
```kotlin
"""Roses are red,
Violets are blue,
sugar is sweet,
And so are you."""
```
# Raw strings, continued
- If you try to print out the raw string in the last slide
you'll find it has
undesirable blanks at the beginning of the last 3 lines.
To eliminate them, Kotlin provides a function `trimMargin()`
so we can write the above raw string as
```kotlin
"""
|Roses are red,
|Violets are blue,
|sugar is sweet,
|And so are you.
""".trimMargin()
```
- The default margin prefix is the `|` character but you can
provide your own and pass it in as argument to `trimMargin()`
like this:
```kotlin
"""
>Roses are red,
>Violets are blue,
>sugar is sweet,
>And so are you.
""".trimMargin(">")
```
# String templates (or string interpolations)
- We have used string templates already.
The simplest string template starts with the `$` character,
followed by a variable name.
Instead of variable name, we can also put an arbitrary expression
enclosed in braces.
- A string template tells Kotlin to construct a new string by
replacing the `$` character and the ensuing variable name or
brace-enclosed expression with its value (after converting
it to a string if necessary).
- For example,
```kotlin
val name = "John"
val age = 20
println("Last year $name was ${age-1} years old.")
```
will print
```
Last year John was 19 years old.
```
# Fine points
- The escape sequences can be used both within character literals
and regular (non raw) string literals. Escape sequences do not
work within raw strings but we can write the newline character
directly within it. Therefore, the two string variables
`s1` and `s2` below have the same content.
```kotlin
val s1 = "One\nTwo\n\Three"
val s2 = """One
Two
Three"""
```
- Both regular string literals and raw strings understand string templates.
- To get the dollar sign into regular string literals, we can escape
it with a backslash like this "\$100".
- However, raw strings don't treat backslash in a special way,
so there must be some other way to specify the dollar sign
within raw strings. We can do it this way
```kotlin
"""That item costs ${'$'}20."""
```
# String functions
- There are lots of string functions that you will find helpful in your
programming. We list some of them here.
```
indexOf( contains(s: CharSequence): Boolean
char: Char, compareTo(other: String,
startIndex: Int = 0, ignoreCase: Boolean = false): Int
ignoreCase: Boolean = false startsWith(prefix: String): Boolean
): Int endsWith(suffix: String): Boolean
isBlank(): Boolean replace(
isNotBlank(): Boolean oldChar: Char,
isEmpty(): Boolean newChar: Char
isNotEmpty(): Boolean ): String
last(): Char replace(
lastIndexOf( target: CharSequence,
char: Char, replacement: CharSequence
startIndex: Int = lastIndex, ): String
ignoreCase: Boolean = false toLowerCase(): String
): Int toUpperCase(): String
repeat(n: Int): String toBoolean(): Boolean
reversed(): String toByte(): Byte
substring(startIndex: Int): String toShort(): Short
substring( toInt(): Int
startIndex: Int, toLong(): Long
endIndex: Int ...
): String trim(): String
```
# Scanner
- A Scanner is a class that allows you to parse many kinds of
numeric and string literals in a text stream.
It is appropriate when the exact format of input is known
beforehand so you can tell it to read in and parse the right
kind of literals at the right time.
- The source code for the Scanner class is written in the
Java programming language.
Since Kotlin-JVM is 100% interoperable with Java,
you can call any Java library function from Kotlin.
Scanner is no exception.
- A concept used by the Scanner is that of _whitespace_.
This term refers to the characters blank (' '),
tab ('\t'), and newline ('\n'), and some others.
Another concept is that of a _cursor_.
Every Scanner object is equipped with a cursor.
It starts scanning the stream by setting the cursor to the beginning
of the stream.
- As you tell the scanner to scan the next input token, it will move the
cursor past any whitespace character until it encounters the first
non-whitespace character. It will then try to read in as much of
the input as possible that can be part of a token for the type of input
it is parsing. It leaves the cursor at the first character that
cannot be part of a valid token for that type of input.
# Scanner, continued
- Let's look at an example of how to scan the standard input.
Suppose our input consists of a sequence of lines that look like this:
```
Albania 2.99 11100
Belgium 10.43 11787
Cuba 11.09 42803
Denmark 5.53 16639
```
- Each line consists of three whitespace-separated pieces of data:
country, population in millions, and area in square miles.
Assume for simplicity that the name of a country is one word,
population is a number with a decimal point, and
area is a whole number.
- We can use the scanner to parse the data like this.
```kotlin
val scanner = java.util.Scanner(System.`in`)
while (scanner.hasNext()) {
val country = scanner.next()
val population = scanner.nextDouble()
val area = scanner.nextInt()
// process data for this country here
}
```
# Useful Scanner functions
- Here is a list of some useful Scanner functions:
```kotlin
hasNext() next()
hasNextLine() nextLine()
hasNextBoolean() nextBoolean()
hasNextByte() nextByte()
hasNextShort() nextShort()
hasNextInt() nextInt()
hasNextLong() nextLong()
hasNextFloat() nextFloat()
hasNextDouble() nextDouble()
```
# Formatted output
- Imagine you have a piece of datum of primitive or string type.
You may want to output it in various ways to make the output
look nice. You can do that using the `String.format` function.
- Let's first learn the concept of a _format specifier_.
It's a string consisting of one required part and three
optional parts
```
"[flags][width][.precision]type"
```
Only type is required.
# Formatted output, continued
- This table shows most of the possible types and their meanings.
type specifier|meaning
:-|:-
%b|Boolean
%c|Char
%d|integral type
%e|floating point type in scientific notation
%f|floating point type in decimal format
%g|floating point type in either decimal or scientific notation, depending on value
%n|line separator
%s|string
%x|integer in hex
%%|The % symbol itself
# Formatted output, continued
- This table shows examples of format specifiers and their effect
on the output string.
type|code|typical literal|sample format strings|converted string values for output
:-|:-|:-|:-|:-
Int|d|512|"%14d"|" 512"
Long|d|512L|"-14d"|"512 "
Float|f|1595.1680010754388F|"14.2f"|" 1595.17"
Double|f|1595.1680010754388|".7f"|"1595.1680011"
Double|e|1595.1680010754388|"14.4e"|" 15952e+03"
String|s|"Hello, world"|"14s"|" Hello, world"
String|s|"Hello, world"|"-14s"|"Hello, world "
String|s|"Hello, world"|"-14.5s"|"Hello "
# Formatted output, continued
- `format` is a String function. You call it using the . operator on the
string whose content is the format specifier, and provide it with as
many arguments as specified in the specifier. Examples:
```kotlin
"%s %d pounds.".format("The baby weighs", 3)
```
gives the string
```
"The baby weighs 3 pounds."
```
_---San Skulrattanakulchai_