The Programmers Guide To Kotlin - Arrays & Strings
Written by Mike James   
Monday, 10 July 2017
Article Index
The Programmers Guide To Kotlin - Arrays & Strings
String Literals

Strings

Kotlin strings are essentially Java strings with some extras. A string is much like an array of chars. You can create a string simply by assigning a string literal to it, for example:

var s="abc"

You can access the individual elements of the string using the [] operator which behaves as if the string was an array of char. Indexing in strings starts from zero just as for arrays.

For example:

var s="abcdef"
println(s[1].javaClass)

Here s[1] is 'b' and the print statement produces  "char", its type.

Like Java, Kotlin strings are immutable and this means you cannot assign to an element. That is:

s[2]='x'

will produce a compile time error. Notice that the string being immutable doesn't mean that a variable referencing a string is immutable. If the variable is declared using val, then it is read only and you cannot assign it a new string, but as long as it is declared as val you can. For example:

var s="abcdef"
s="xyz"

is perfectly OK.

Operations with immutable strings generally involve taking sections from the existing strings and putting them together to create a completely new string. 

There are many string methods that allow you to extract part of a string and the concatenation operator + allows you to join them together. The most often used string method is substring which comes in a large number of forms which allow you to specify the start and end of the substring you want. The version that is most idiomatic Kotlin, however, is

substring(range)

where range specifies the start and end indices of the substring you want. For example:

s="abcdef"
println(s.substring(0..2))

prints abc. Using substring and + you can write an expression that appears to change, say, the third element of the string:

var s="abcdef"
s=s.substring(0..1)+"x"+s.substring(3..s.length-1)

This works by extracting "ab" and "def" and putting them back together with "x" between them. Notice that this only looks as if the third element of the original string has changed. In fact what has happened is that a whole new string has been constructed and assigned to s. The old string, assuming it hasn't any other variables referencing it, will eventually be garbage collected.  

To convert this into a general expression for replacing the ith character all you need is:

s=s.substring(0..i-1)+"x"+
                  s.substring(i+1..s.length-1)

Of course you need to account for the special cases i=0 and i=length-1. Notice that x here is a string as we are concatenating strings.

Working in this way you can do anything with an immutable string that a mutable string would let you do. The reason for using immutable strings is that they make memory allocation simpler as they have a fixed size. The downside is that any changes you need to make involve creating a new string and abandoning the old. This is generally efficient in time, but not in memory.

If you want a mutable string then you can use the Java StringBuilder class:

var s=StringBuilder("abcdef")
s[2]='x'

Notice that x has to be a char because StringBuilder is like an array of chars.

The StringBuilder allocates a char buffer that is slightly larger than the string you give it to initialize it and uses this extra space if you want to add chars to the string. Once this space is used up the StringBuilder allocates more memory and this can be a slow process. You can also create a StringBuilder with a specific initial capacity. StringBuilder also has the insert and append methods which can be used to insert and append text. 

String Literals

Next we come to the interesting subject, in Kotlin, of String literals. 

There are two type of Kotlin string literals - escaped and raw. 

An escaped literal is what you are most likely to be familiar with. You can include escaped characters by placing a \ in front which changes the meaning of the character. 

For example:

print("Hello World \n"

includes a newline code, rather than an n, at the end of the string. 

The standard escaped characters in Kotlin are:

\t  tab
\b  backspace
\n  newline
\r  carriage return
\
'  single quote
\"  double quote
\\  slash
\$  dollar

Notice that single quote, double quote, slash and dollar escapes have the effect of converting characters that by default have a special meaning to just ordinary characters.

The meaning of the dollar sign as a special character in Kotlin strings will be explained later.

You can also include any Unicode character found in in the Basic Multilingual Plane (BMP), i.e the first 65000 characters or so, using 

\uHHHH

where H is a hexadecimal integer. 

For example:

var s = "\u016C"

stores the Latin Extended-A block capital letter U with breve, i.e. Ŭ

Note that Java, and hence Kotlin, does not support two word UTF-16 codes so you are restricted to the BMP and 16-bit codes. 

The new raw string literal in Kotlin is designed to make entering longer and formatted text easier. A raw string literal is indicated by three double quotes. A raw string can contain no escape characters, but it can contain any character you can enter including control characters such as newline, etc. As the raw string is delimited by """ you can have a single double quote and a double double quote but not a triple double quote within a raw string. Also note that the raw string includes all of the characters between the delimiters, including any that the code editor might add in formatting your program. 

For example:

var s="""Hello World"""
print(s)

just prints Hello World with no changes. However:

var s = """Hello
   World"""
    print(s)

as automatically formatted by IntelliJ, prints:

Hello
   World

You can include an initial and final newline by putting the """ on lines of their own:

var s = """
Hello
World
"""

Perhaps the most useful new feature in Kotlin strings is the template. Put simply, you can include an expression that will be evaluated when the string is constructed and inserted into the string. An expression is indicated by a leading dollar sign followed by an expression in curly brackets. If the expression is a single variable then the curly brackets can be omitted. 

So for example:

var s="Name $name and Address $address"

will insert the values of the variables name and address into the string. Of course, the variables have to contain a string or have valid ToString methods that provide the appropriate text. 

It is very important to understand that string templates are evaluated only once, i.e. when the string is constructed - the expressions are not live and will not be re-evaluated.

For example, consider the following: 

var i = 1
var s = "The value of I is $i"
println(s)
i = 2
println(s)

Even though the value of i has changed the second printlin still prints:

The value of I is 1. 

Compare this to:

var i = 1
println("The value of I is $i")
i = 2
println("The value of I is $i")

Now you see the correct value of I each time, i.e. it prints:

"The value of I is 1"
"The value of I is 2"

The reason, of course, is that there are two different string literals being used and each is constructed at the same time as the println it is used in.

Using string templates within print statements is one way to achieve a more complex display. For example:

println("Name $name and Address $address")

The problem here is that string templates don't, yet, have any format control. That is, how can you print a value to say three decimal places? Using just Kotlin you can't, unless you write a function to do the job. However,

System.out.printf("The value of Pi is %.3f",pi)

This prints 3.141, i.e. pi to three decimal places. 

A slightly more Kotlin-oriented version of the same idea is to use Java's format string method:

println("The value of Pi is %.3f".format(pi))

Eventually no doubt Kotlin will acquire its own formatted templates, but for now we can fall back on Java.

You can use templates in both escaped and raw strings. In an escaped string you can enter a $ sign using \$. How can we enter a $ in a raw string?

The answer is obvious after a moment's thought. You can use an expression which returns a dollar sign as a literal. That is to enter a $ into a raw string simply use:

"""this is a raw string $('$')
with a dollar symbol"""

The number of functions available in the String class is huge and you can spend a great deal of time exploring them all. In general, if you want to do something check the documentation for a function that can do the job for you or can help with the problem. In particular, remember that Kotlin supports Java's regular expressions, which can solve many problems in one go.  

Programmer's Guide To Kotlin Second Edition

kotlin2e360

You can buy it from: Amazon

Contents

  1. What makes Kotlin Special
  2. The Basics:Variables,Primitive Types and Functions 
  3. Control
         Extract: If and When 
  4. Strings and Arrays
  5. The Class & The Object
  6. Inheritance
  7. The Type Hierarchy
  8. Generics
  9. Collections, Iterators, Sequences & Ranges
        Extract: Iterators & Sequences 
  10. Advanced functions 
  11. Anonymous, Lamdas & Inline Functions
  12. Data classes, enums and destructuring
        Extract: Destructuring 
  13. Exceptions, Annotations & Reflection
  14. Coroutines
        Extract: Coroutines 
  15. Working with Java
        Extract: Using Swing ***NEW!

<ASIN:B096MZY7JM>

 kotlinlogo

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 

Banner


The Appeal of Google Summer of Code
21/03/2024

With the list of participating organizations now published, it is time for would-be contributors to select among them and apply for Google Summer of Code (GSoC). Rust has joined in the program fo [ ... ]



Apache Shiro 2.0 Released
21/03/2024

Apache Shiro 2.0 has been released. The Java security framework now requires at least Java 11, and has added support for Jakarta EE 10.


More News

raspberry pi books

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Monday, 10 July 2017 )