1 The Problem
We want a small program that converts a temperature from Celsius to Fahrenheit, or the other way around. The user picks which direction, types a number, and the program does the maths and shows the answer. Simple — but it teaches the core shape of every calculator-style tool: ask, calculate, show.
2 How to Think About It
Six formulas, one direction code each. The whole program is: ask which direction, ask the value, apply the right formula, print the result.
3 The Build — explained part by part
Here is the complete converter, with the actual conversion logic pulled into one small, independently testable method.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Temperature Converter: converts a value between Celsius, Fahrenheit, and
* Kelvin based on a direction the user picks.
*/
public class TemperatureConverter {
/**
* Converts {@code value} according to {@code choice}, one of
* "c2f", "f2c", "c2k", "k2c", "f2k", or "k2f".
*
* @throws IllegalArgumentException if choice is not one of the six directions
*/
static double convert(String choice, double value) {
return switch (choice) {
case "c2f" -> value * 9.0 / 5.0 + 32;
case "f2c" -> (value - 32) * 5.0 / 9.0;
case "c2k" -> value + 273.15;
case "k2c" -> value - 273.15;
case "f2k" -> (value - 32) * 5.0 / 9.0 + 273.15;
case "k2f" -> (value - 273.15) * 9.0 / 5.0 + 32;
default -> throw new IllegalArgumentException("Unknown conversion: " + choice);
};
}
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Convert (c2f, f2c, c2k, k2c, f2k, k2f): ");
String choice = in.readLine().trim();
System.out.print("Value: ");
double value = Double.parseDouble(in.readLine().trim());
double result = convert(choice, value);
System.out.printf("%.2f -> %.2f%n", value, result);
}
}
double, kept separate from I/O so it is testable without any stdin involved.switch (choice) { case "c2f" -> ...; default -> throw ...; } — the modern arrow-form switch expression from the course’s Control Flow lesson: no fall-through to worry about, and it directly produces a value rather than needing a separate
result = ... assignment in every branch.default -> throw new IllegalArgumentException(...) — an unrecognized direction code fails loudly and immediately with a clear message, rather than silently returning a wrong number or crashing somewhere unrelated later.
System.out.printf("%.2f -> %.2f%n", ...) —
%.2f rounds to two decimal places, and %n is the platform-correct newline (unlike a hardcoded \n, it becomes \r\n automatically on Windows).
.trim() on the choice string before the switch — a line read from stdin keeps its trailing newline, so "c2f\n" never matches the case label "c2f"..trim() a line read from stdin before comparing or switching on it.9 / 5 on int truncates to 1, silently breaking every conversion.9.0 / 5.0, as the code above does.4 Test & Prove Each Part
We test the conversion formulas directly, and the invalid-direction case, without ever needing to type anything.
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TemperatureConverterTest {
@Test
public void celsiusToFahrenheit() {
assertEquals(212.0, TemperatureConverter.convert("c2f", 100), 0.001);
assertEquals(32.0, TemperatureConverter.convert("c2f", 0), 0.001);
}
@Test
public void fahrenheitToCelsius() {
assertEquals(0.0, TemperatureConverter.convert("f2c", 32), 0.001);
}
@Test
public void kelvinRoundTrip() {
assertEquals(273.15, TemperatureConverter.convert("c2k", 0), 0.001);
assertEquals(-273.15, TemperatureConverter.convert("k2c", 0), 0.001);
}
@Test(expected = IllegalArgumentException.class)
public void unknownDirectionThrows() {
TemperatureConverter.convert("x2y", 10);
}
}
Compile and run with the same JUnit classpath as the previous project: javac -cp junit-4.13.2.jar and hamcrest-core-1.3.jar TemperatureConverter.java TemperatureConverterTest.java then java -cp .:junit-4.13.2.jar:hamcrest-core-1.3.jar org.junit.runner.JUnitCore TemperatureConverterTest. Floating-point results are compared with a small tolerance (0.001) rather than exact equality — comparing doubles for exact equality is a classic bug in any language.
5 The Interface
What it expects
Direction: "c2f", "f2c", "c2k", "k2c", "f2k", or "k2f"
Value: a number like 100What it returns
100.00 -> 212.006 Run It & Automate It
Save the code as TemperatureConverter.java and compile it with javac — that turns your source into .class bytecode files, which java then runs on the JVM. No separate install step: any real JDK ships both tools.
javac TemperatureConverter.java && java TemperatureConverterEnter a direction code, then the temperature value.
A CI tool like Jenkins runs the same compile-then-test steps automatically whenever the code changes — every line below has a plain explanation.
Convert (c2f, f2c, c2k, k2c, f2k, k2f): c2f
Value: 100
100.00 -> 212.00double. Make sure it is a plain number like 100 or 36.6, with no stray letters or units.\r\n rather than just \n. .trim() already strips both, so if you see this, check you did not remove that call before the switch.// Jenkinsfile — runs the tests automatically every time the code changes.
pipeline {
agent any // run on any available machine
environment {
CP = 'junit-4.13.2.jar:hamcrest-core-1.3.jar' // JUnit + its one dependency
}
stages {
stage('Get the code') {
steps { checkout scm } // download the latest code
}
stage('Set up JDK') {
steps {
sh 'java -version' // confirm a JDK is installed
sh 'javac -cp "$CP" *.java' // compile the program and its tests together
}
}
stage('Run the tests') {
steps {
sh 'java -cp ".:$CP" org.junit.runner.JUnitCore TemperatureConverterTest'
}
}
}
post {
success { echo 'All tests passed.' }
failure { echo 'A test failed — look above.' }
}
}
- Add Rankine. A seventh and eighth case in the switch expression. (Teaches: extending an exhaustive-feeling switch safely.)
- Accept a command-line argument. Read from
argsinstead of a menu. (Teaches: non-interactive CLI design.) - Round-trip validation. Warn if converting forward then back does not return the original value within a tolerance. (Teaches: floating-point comparison.)
switch expression, throwing a clear exception on invalid input instead of guessing, and why floats should never be compared for exact equality. Related: Control Flow, Variables and Types.