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

  • Streams : 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

  • Static : 02/23/2024

  • Encapsulation : 02/22/2024

  • Constructors : 02/21/2024

  • Objects, Continued : 02/20/2024

  • Introduction to Objects : 02/19/2024

  • Compilation and Type Inference : 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

Compilation and Type Inference

var i = 1;
var j = "1";

Welcome back to CS 124! You are not alone.

This lesson is a lot of fun. We’ll spend some time on our first discussion of Java internals. Specifically, we’ll explain more about what happens when your code is run. Then we’ll discuss Java type inference.

Warm Up Debugging Challenge
Warm Up Debugging Challenge

Let’s warm up with another graded debugging challenge!

Compilation and Execution
Compilation and Execution

Our focus in this class is on teaching you to think computationally and express those thoughts coherently in the Java programming language. Once you do that, you’ll be able to learn other programming languages easily and accomplish other computational tasks.

So we don’t spend a lot of time on exactly what is going on under the hood when Java executes the code that you submit. On some level, it doesn’t matter. As long as the core language constructs have a stable meaning, the internals of how things work don’t matter. When I write:

for (int i = 0; i < 8; i++) {
System.out.println("Happy birthday!");
}

I expect to see a message displayed 8 times. Java could and might completely change exactly how that is accomplished, but as long as it is accomplished, I’m not going to notice. This is a powerful idea in computer science, even if at times the methods of implementation are somewhat less than practical.

But! In this case having a bit of an understanding of what is happening is actually useful. And, what is actually happening is quite interesting! So let’s peek under the hood…

Two Steps
Two Steps

When you run a Java program there are actually two distinct steps that are taking place:

  1. Compilation: in this step your Java source code is compiled or translated into a different set of simpler instructions. The compiler can and does catch certain kinds of errors at this stage.
  2. Execution: the Java compiler produces a file containing bytecode, which can then be executed. This is when you program actually runs and does whatever you’ve instructed it to do. There are other errors that can occur at this stage.

Compilation
Compilation

Let’s talk a bit about when compilation happens, what is produced, and the kind of errors that the compiler can produce during this step.

Execution
Execution

Now let’s return to the same environment and discuss the execution step and the kind of errors that can occur at that point.

Development v. Production
Development v. Production

One of the reasons understanding these steps is so important is that they have a relationship to the difference between development and production:

Compiler errors generally only happen in development. That means that only developers see them! In contrast, runtime errors can happen in production! That means they might affect actual users.

Software developers acquire a high degree of patience with broken and crashy software. Users do not. That means that, if you can reduce runtime errors and catch them during development, you will produce better software. A new generation of compilers aim to do just that. Which would prevent you being able to do this, which always strikes me as insanely dumb:

// WHY DOES JAVA LET ME DO THIS!?!?!?!
String s = null;
System.out.println(s.length());

Practice: List to Set

Created By: Geoffrey Challen
/ Version: 2021.9.0

Given a List of Strings, write a method toSet that converts the List to a Set of Strings that contains all the same Strings in the original list. So given a List containing "test", "me", and "test", you would return a Set containing "test" and "me". assert that the passed List is not null.

Java Type Inference
Java Type Inference

Before we conclude, let’s look at a new Java feature: type inference.

Let’s return to the very beginning of our experiences with Java. As a reminder, Java requires that we provide a type when we declare a variable:

int i;

This is a variable named i that can store values of type int. We know this.

But it’s more common to both declare and initialize a variable in the same statement:

int i = 0;

This is a variable named i that can store values of type int that we initialize to 0. We know this too.

But let’s look more carefully at this common and seemingly innocuous statement:

int i = 0;

Notice something interesting? We’ve actually told Java the type of the variable i twice. Once through the declaration, but a second time through initialization. Let’s split them apart:

int i; // Type named via declaration
i = 0; // Type indicated via initialization

So the Java compiler could determine the type based on how we initialize the variable. This is known as type inference, since the compiler infers the variable type based on how it is used. (Assignment is just one example of usage. We’ll look at another.)

The Java compiler is not particularly sophisticated. But, since Java version 10, it can infer types in certain situations. Here’s how to enable that:

// Show how to enable Java type inference

Pretty cool! Note that this limited form of type inference is available in our playgounds, and for you to use on your homework problems. (It may not work when we get to the Android project, because Android is using an older version of Java.)

Practice: String Duplicate Words Ignore Case

Created By: Geoffrey Challen
/ Version: 2021.9.0

Given a String containing words separated by the " " (space) character, write a method hasDuplicateWords that returns true if any word appears twice in the String. Also, you should ignore case: so "Chuchu" and "chuchu" are considered the same word. assert that the passed String is not null.

So, for example, given the String "Wow that is amazing", you would return false, but given the String "Chuchu chuchu xyz" you would return true.

Our intention is for you to solve this problem using a Set, but there are also solutions that use a Map. You should not use a nested loop to solve this problem. You may want to use the toLowerCase method of Java Strings.

Script Parser Warm-Up
Script Parser Warm-Up

Next let’s discuss how to approach our next practice homework problem. This problem is a bit trickier, since we need to determine when to properly insert entries into our Map, and do some String parsing. So let’s discuss how to get started.

Please don’t attempt this practice problem until you are done with yesterday’s homework problem!

// Warm-up for Script Parser
Created By: Geoffrey Challen
/ Version: 2022.2.0

Write a method called parseScript that accepts a single String and returns a Map<String, List<String>>. The passed String contains a script consisting of lines separated by newlines, each with the following format:

Name: Line

For example, here's a simple script:

Geoffrey: What do you think of this homework problem?
Ahmed: it's a bit sus
Geoffrey: I bet they'll be able to figure it out!
Maaheen: We'll be here to help if they need it.

parseScript parses the script and returns a map mapping each character's name to their lines in order. So, for the script above, the map would contain three keys: "Geoffrey", "Ahmed", and "Maaheen". The List<String> for the key "Geoffrey" would contain the Strings "What do you think of this homework problem!" and "I bet they'll be able to figure it out!" The List<String> for the key "Amhed" would contain the String "it's a bit sus".

A few hints for approaching this problem.

You'll want to use .split to parse the passed String into individual lines. You should assert that the passed String is not null, but if it's not, it will have the format described above, and also not contain any blank lines.

You'll also need to use .split to split each line into the name and their line of dialog. You can assume that the character ":" only appears to delimit the name of the rest of the line.

The first time you encounter a character, there will not be an entry in your map for them. So you should check for this, and create the ArrayList when appropriate.

There may be extra whitespace around the name or the line of dialogue, so use .trim appropriately.

The following imports are provided for you: java.util.List, java.util.ArrayList, java.util.Map, and java.util.HashMap. You should not need to use other imports to solve this problem.

No New Homework Today
No New Homework Today

Please continue to work on yesterday’s more challenging problem. Good luck! Jump on the tutoring site or find us on the forum when you need some assistance. And keep in mind that this is just one problem…

More Practice

Need more practice? Head over to the practice page.