KotlinCS 124 LogoJava
PrevIndexNext
Kotlin
Java
  • Implementing a Map : 04/26/2024

  • map-reduce-filter : 04/25/2024

  • Generics : 04/24/2024

  • Hashing : 04/23/2024

  • Binary Search : 04/22/2024

  • MP3: Course Ratings : 04/19/2024

  • Quicksort : 04/18/2024

  • Merge Sort : 04/17/2024

  • Sorting Algorithms : 04/16/2024

  • MP Debugging Part 1 : 04/15/2024

  • MP2: Course Activity : 04/12/2024

  • Practice with Recursion : 04/11/2024

  • MP Debugging Part 0 : 04/10/2024

  • MP2: API Client : 04/09/2024

  • MP2: API Server : 04/08/2024

  • Trees and Recursion : 04/05/2024

  • Trees : 04/04/2024

  • Recursion : 04/03/2024

  • MP1: Filtering and Search : 04/02/2024

  • MP1: Loading and Sorting : 04/01/2024

  • Lists Review and Performance : 03/29/2024

  • Linked Lists : 03/28/2024

  • Algorithms and Lists : 03/27/2024

  • Continuing MP0 : 03/26/2024

  • Getting Started with MP0 : 03/25/2024

  • Lambda Expressions : 03/22/2024

  • Anonymous Classes : 03/21/2024

  • Practice with Interfaces : 03/20/2024

  • Implementing Interfaces : 03/19/2024

  • Using Interfaces : 03/18/2024

  • Working with Exceptions : 03/08/2024

  • Throwing Exceptions : 03/07/2024

  • Catching Exceptions : 03/06/2024

  • References and Polymorphism : 03/05/2024

  • References : 03/04/2024

  • Data Modeling 2 : 03/01/2024

  • Equality and Object Copying : 02/29/2024

  • Polymorphism : 02/28/2024

  • Inheritance : 02/27/2024

  • Data Modeling 1 : 02/26/2024

  • Companion Objects : 02/23/2024

  • Encapsulation : 02/22/2024

  • Constructors : 02/21/2024

  • Objects, Continued : 02/20/2024

  • Introduction to Objects : 02/19/2024

  • Compilation and Immutability : 02/16/2024

  • Practice with Collections : 02/15/2024

  • Maps and Sets : 02/14/2024

  • Lists and Type Parameters : 02/13/2024

  • Imports and Libraries : 02/12/2024

  • Multidimensional Arrays : 02/09/2024

  • Practice with Strings : 02/08/2024

  • null : 02/07/2024

  • Algorithms and Strings : 02/06/2024

  • Strings : 02/05/2024

  • Functions and Algorithms : 02/02/2024

  • Practice with Functions : 02/01/2024

  • More About Functions : 01/31/2024

  • Errors and Debugging : 01/30/2024

  • Functions : 01/29/2024

  • Practice with Loops and Algorithms : 01/26/2024

  • Algorithms : 01/25/2024

  • Loops : 01/24/2024

  • Arrays : 01/23/2024

  • Compound Conditionals : 01/22/2024

  • Conditional Expressions and Statements : 01/19/2024

  • Operations on Variables : 01/18/2024

  • Variables and Types : 01/17/2024

  • Welcome to CS 124 : 01/16/2024

MP1: Loading and Sorting

Let’s continue our work on the machine project! We’ll begin our first real project checkpoint, MP1, and get some practice with Jackson, the JSON serialization library used in our app. We’ll install the test suites and begin work on our first test case.

But most of this lesson is tracing how data flows through our app, and discussing various ways in which data is stored and retrieved from Strings. We’ll also discuss how the list view component we use works. Your programming task for this lesson is fairly straightforward, and we’ll guide you to it.

Getting Started
Getting Started

For MP1 we’ll be continuing on with the project that you started working on for MP0. You’ll need the environment that you set up during that checkpoint to proceed.

Before you can get to work on MP1 in earnest, we need to install the MP1 test suites. Before we continue, please commit your work. You should make sure to commit both immediately before and immediately after we install the MP1 test suites. (If there are no changes to commit beforehand, that’s fine.)

You’ll receive the MP1 Kotlin test suites via email. Move the file to the app/src/test/kotlin/edu/illinois/cs/cs124/ay2023/mp/test/ directory in your machine project. You’ll also want to reconfigure grade.yaml in the root directory of your project to request that we grade Checkpoint 1. Let’s look at how to do both of these things together:

Serialization
Serialization

Today we’ll examine how data flows through our app. Along the way, we’ll naturally encounter a process called serialization. But what does that mean? Wikipedia defines serialization as:

In computing, serialization is the process of translating a data structure or object state into a format that can be stored (for example, in a file or memory data buffer) or transmitted (for example, across a computer network) and reconstructed later (possibly in a different computer environment). When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object. For many complex objects, such as those that make extensive use of references, this process is not straightforward. Serialization of object-oriented objects does not include any of their associated methods with which they were previously linked.

JSON
JSON

If serialization is the process of converting object state into some format, what format should we use? There are many different options. But one particularly popular and ubiquitous object serialization format that we use in the MP is known as JSON: JavaScript Object Notation.

Here’s one example. This object has one field named example with the value test:

{
"example": "test"
}

In JSON, each object is enclosed in curly braces: { and }s. Arrays are enclosed in square brackets:

{
"values": [1, 2, 4, 8]
}

Numeric literals are not quoted, but all field names and most other values are.

Note that JSON requires the entire object to be represented as a string. For actual Strings and certain other Kotlin classes there is an obvious way to do this. In other cases, it’s a bit more interesting. We’ll look at how some other Kotlin classes convert themselves to Strings in the examples below.

Why JSON?
Why JSON?

There are really two questions here. First, why serialization at all? Second, why the JSON format?

As we discussed above, serialization is one very powerful way to pass data between two different computer programs. In your app, JSON is how data about the list of courses is passed from the server to the client, which would normally be running on two different machines and communicating over a network connection. Because there are JSON libraries for almost every programming language, most can use JSON to communicate, meaning that a client written in Kotlin, or Java, or Python, or Lisp can talk to a server in Java, or Python, or Go, or Haskell. We’ll see a concrete example of serialization when we examine the data path in our app below.

Jackson
Jackson

Next, let’s examine how we can use JSON in our Kotlin programs. This is one of the many things that you should never do yourself! There are many great libraries that support JSON in Kotlin programs.

We’re going to be using a library called Jackson to assist us with serialization. Next, let’s look at how we can use Jackson to serialize and deserialize our Kotlin objects!

Serialization using Jackson
Serialization using Jackson

Let’s start with serialization. Here’s how to use Jackson to automatically generate JSON from our Kotlin objects:

// Serializing a Kotlin object using Jackson

Deserialization
Deserialization

Now that we have a string, let’s look at how we can deserialize that String and convert it back into a Kotlin object.

// Deserializing a Kotlin object using Jackson

Practice with Serialization
Practice with Serialization

The following homework problem is only for practice, but it may help you understand how to complete later parts of the MP.

Created By: Geoffrey Challen
/ Version: 2020.10.0

Up until now we've used public constructors to create instances of our classes. But there are other patterns for enabling class creation, and this problem explores one. Specifically, we're going to show how to deserialize a CSV String into instances of a custom class.

Create a class named Course. Course should not provide a public constructor, although you will probably want to create a private one. Instead, Course should provide method named fromCSV on a companion object which takes a single String argument and returns an array of Course instances.

Each Course maintains a department and a number, both Strings. Here's how they are loaded from a CSV String. Given the following CSV contents:

 CS, 125
IE, 333
  MUS, 230

You should return an array containing three Course instances: the first with department="CS" and number="125", the second with department="IE" and number="333", etc. Your array should contain the courses in the same order in which they appear in the CSV String. You should require that the passed String is not empty.

To complete this problem you'll want to review our previous work with CSV Strings, apply what you know about companion objects, and determine how to create a private constructor. Have fun!

Data Model
Data Model

Now that we understand a bit about serialization, let’s return to our app and see it in action!

Your app works with data about courses at the University of Illinois. This involves both serializing that data to and from JSON, but also designing data models using class design features. Let’s look at the core data model you’ll be using during MP1, and examine where the data comes from and how it flows through your app.

Comparing Summaries
Comparing Summaries

Finally, let’s zero in on our first MP1 test case, and discuss how to correctly implement Comparable for your Summary model. Your default comparison should compare summaries first by their number, and next by their subject. For example, “IS 100” should be shown after “CS 100” but before “STAT 200”.

Let’s briefly examine where you need to make changes, and how to test your compareTo method.

Once you’re passing test0_SummaryComparison, it’s a small change to also complete test2_SummaryView. The video walkthroughs above should give you a hint. Also notice that, once a class implements Comparable, you can sort it using Kotlin’s built-in sorting methods, as shown below. Do not implement your own sort method! We’ll do that together later.

class Person(val name: String) : Comparable<Person> {
override fun compareTo(other: Person): Int {
return name.compareTo(other.name)
}
override fun toString() = name
}
val people = mutableListOf<Person>(Person("Geoff"), Person("Michael"), Person("Jule"))
println(people)
people.sort() // sort the list
println(people) // now sorted by name

Your Goal Today
Your Goal Today

As a reminder, on lessons where we focus on the machine project we will not assign a homework problem! However, the lesson will usually focus on helping you complete a particular part of the MP test suite, and so we encourage you to spend time on that in lieu of a homework problem.

Right now your goal should be to

  1. install the MP1 test suites
  2. get your code to compile, and
  3. implement summary sorting correctly—both in the Summary class and in the MainActivity, so that summaries are sorted properly when the app starts
  4. at that point you’ll be passing test0_SummaryComparison and test2_SummaryView

If you get stuck, find us for help on the tutoring site or forum. If you have extra time after today’s lesson, you may want to move on and begin work on the next lesson, which also covers MP1.

MP1 Scores
MP1 Scores