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.
Let’s warm up with another debugging challenge!
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:
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…
When you run a Java program there are actually two distinct steps that are taking place:
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.
Now let’s return to the same environment and discuss the execution step and the kind of errors that can occur at that point.
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:
Given a List
of String
s, write a method toSet
that converts the List
to a Set
of Strings
that contains
all the same String
s 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
.
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:
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:
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:
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:
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:
Pretty cool! Note that this limited form of type inference is available in our playgounds, and for you to use on your homework problems. However, it does not work on older versions of Java.
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 String
s.
Need more practice? Head over to the practice page.