Chapter 15. Handling Data and Generating Random Numbers
We are making good progress. We have a rounded knowledge of both the Android UI options and the basics of Kotlin. In the previous few chapters, we started bringing these two areas together and we manipulated the UI, including some new widgets, using Kotlin code. However, while building the Note to self app, we have stumbled upon a couple of blanks in our knowledge. In this chapter, we will fill in the first of these blanks, and then, in the next chapter, we will use this new information to progress with the app. We currently have no way of managing large amounts of related data. Aside from declaring, initializing, and managing dozens, hundreds, or even thousands of properties or instances, how will we let the users of our app have more than one note? We will also take a quick diversion to learn about random numbers.
We will cover the following topics in this chapter:
Random numbers
Arrays
A simple array mini-app
A dynamic array mini-app
Ranges...
Sometimes, we will want a random number in our apps and, for these occasions, Kotlin provides us with the Random
class. There are many possible uses for this class, such as if our app wants to show a random tip-of-the-day, or a game that has to choose between scenarios, or a quiz that asks random questions.
The Random
class is part of the Android API and is fully compatible in our Android apps.
Let's take a look at how to create random numbers. All the hard work is done for us by the Random
class. First, we need to create a Random
object, as follows:
Then, we use our new object's nextInt
function to generate a random number between a certain range. The following line of code generates the random number using our randGenerator
object and stores the result in the ourRandomNumber
variable:
The number that we enter for the range starts from zero. So, the preceding line will generate a random number between...
Handling large amounts of data with arrays
You might be wondering what happens when we have an app with lots of variables to keep track of. What about our Note to self app with 100 notes, or a high-score table in a game with the top 100 scores? We can declare and initialize 100 separate variables as follows:
Or, by using the high scores example we might use something like the following code:
Immediately, this code can seem unwieldy, but what about when someone gets a new top score, or if we want to let our users sort the order that their notes are displayed in? Using the high scores scenario, we must shift the scores in every variable down one place. This is the beginning of a nightmare, as shown in the following code:
A simple mini-app array example
Let's make a simple working array example. You can get the completed code for this project in the downloadable code bundle. It can be found in the Chapter15/Simple Array Example/MainActivity.kt
file.
Create a project with an Empty Activity project template and call it Simple Array Example
.
First, we declare our array, allocate five spaces, and initialize values to each of the elements. Then, we output each of the values to the logcat window.
This is slightly different to the earlier examples that we have seen because we declare the size at the same time as we declare the array itself.
Add the following code to the onCreate
function just after the call to setContentView
:
Getting dynamic with arrays
As we discussed at the beginning of this section, if we need to declare and initialize each element of an array individually, there isn't a huge benefit to using an array over regular variables. Let's take a look at an example of declaring and initializing arrays dynamically.
You can get the working project for this example in the download bundle. It can be found in the Chapter15/Dynamic Array Example/MainActivity.kt
file.
Create a project with an Empty Activity template and call it Dynamic Array Example
.
Type the following code just after the call to setContentView
in the onCreate
function. See if you can work out what the output will be before we discuss and analyze the code:
An ArrayList
object is like a normal array, but on steroids. It overcomes some of the shortfalls of arrays, such as having to predetermine its size. It adds several useful functions to make its data easy to manage and it is used by many classes in the Android API. This last point means that we need to use ArrayList
if we want to use certain parts of the API. In Chapter 16, Adapters and Recyclers, we will put ArrayList
to work for real. First the theory.
Let's take a look at some code that uses ArrayList
:
In the preceding code, we declared and initialized a new ArrayList
object called myList
. We can also do this in a single step, as demonstrated by the following code:
So far, this is not particularly interesting, so let's take a look at what we can actually do with ArrayList
. Let's...
Arrays and ArrayLists are polymorphic
We already know that we can put objects into arrays and ArrayList
objects. However, being polymorphic means that they can handle objects of multiple distinct types as long as they have a common parent type – all within the same array or ArrayList
.
In Chapter 10, Object-Oriented Programming, we learned that polymorphism means many forms. But what does it mean to us in the context of arrays and ArrayList
?
In its simplest form, it means that any subclass can be used as part of the code that uses the super-class.
For example, if we have an array of Animals
, we can put any object that is a subclass of Animal
in the Animals
array, such as Cat
and Dog
.
This means we can write code that is simpler, easier to understand, and easier to change:
Kotlin HashMap
s are interesting; they are a type of cousin to ArrayList
. They encapsulate useful data storage techniques that would otherwise be quite technical for us to code successfully ourselves. It is worth looking at HashMap
before getting back to the Note to self app.
Suppose that we want to store the data of lots of characters from a role-playing game and each different character is represented by an object of the Character
type.
We could use some of the Kotlin tools that we already know about, such as arrays or ArrayList
. However, with HashMap
, we can give a unique key or identifier to each Character
object, and access any such object using that same key or identifier.
Note
The term "hash" comes from the process of turning our chosen key or identifier into something used internally by the HashMap
class. The process is called hashing.
Any of our Character
instances can then be accessed with our chosen key or identifier. A good candidate for a key or identifier in the Character...
Despite all we have learned, we are not quite ready to apply a solution to the Note to self app. We could update our code to store lots of Note
instances in an ArrayList
, but before we do, we also need a way to display the contents of our ArrayList
in the UI. It won't look good to throw the whole thing in a TextView
instance.
The solution is adapters, and a special UI layout called RecyclerView
. We will get to them in the next chapter.
Frequently asked questions
Q) How can a computer that can only make real calculations possibly generate a genuinely random number?
A) In reality, a computer cannot create a number that is truly random, but the Random
class uses a seed that produces a number that will stand up as genuinely random under close statistical scrutiny. To find out more about seeds and generating random numbers, look at the following article: https://en.wikipedia.org/wiki/Random_number_generation.
In this chapter, we looked at how to use simple Kotlin arrays to store substantial amounts of data provided that it is of the same type. We also used ArrayList
, which is like an array with lots of extra features. Furthermore, we discovered that both arrays and ArrayList
are polymorphic, which means that a single array (or ArrayList
) can hold multiple different objects as long as they are all derived from the same parent class.
We also learned about the HashMap
class, which is also a data storage solution, but which allows access in different ways.
In the next chapter, we will learn about Adapter
and RecyclerView
to put the theory into practice and enhance our Note to self app.