
You’ve learned variables, operators, methods, and user input. Now it’s time to build something real. This calculator project combines those skills into a working application you can actually use.
We’ll build it in stages, starting simple and adding features. By the end, you’ll have a calculator that handles basic arithmetic, validates input, and keeps running until the user decides to quit.
What We’re Building
The calculator will:
- Accept two numbers from the user
- Let the user choose an operation (add, subtract, multiply, divide)
- Display the result
- Handle invalid input gracefully
- Allow multiple calculations without restarting
This covers fundamental programming concepts: input/output, conditionals, loops, methods, and error handling.
Stage 1: Basic Structure
Start with the simplest version. Get two numbers, add them, print the result.
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter first number: ");
double num1 = scanner.nextDouble();
System.out.print("Enter second number: ");
double num2 = scanner.nextDouble();
double result = num1 + num2;
System.out.println("Result: " + result);
scanner.close();
}
}
Run it:
Enter first number: 10
Enter second number: 5
Result: 15.0
It works, but only does addition. Let’s add operation selection.
Stage 2: Multiple Operations
Add a menu for choosing the operation. Use a switch statement to handle each choice.
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter first number: ");
double num1 = scanner.nextDouble();
System.out.print("Enter second number: ");
double num2 = scanner.nextDouble();
System.out.println("\nSelect operation:");
System.out.println("1. Add");
System.out.println("2. Subtract");
System.out.println("3. Multiply");
System.out.println("4. Divide");
System.out.print("Choice: ");
int choice = scanner.nextInt();
double result;
switch (choice) {
case 1:
result = num1 + num2;
System.out.println(num1 + " + " + num2 + " = " + result);
break;
case 2:
result = num1 - num2;
System.out.println(num1 + " - " + num2 + " = " + result);
break;
case 3:
result = num1 * num2;
System.out.println(num1 + " * " + num2 + " = " + result);
break;
case 4:
result = num1 / num2;
System.out.println(num1 + " / " + num2 + " = " + result);
break;
default:
System.out.println("Invalid choice");
}
scanner.close();
}
}
Sample run:
Enter first number: 20
Enter second number: 4
Select operation:
1. Add
2. Subtract
3. Multiply
4. Divide
Choice: 4
20.0 / 4.0 = 5.0
Better. But what happens if someone divides by zero?
Stage 3: Input Validation
Division by zero causes problems. Let’s check for it. We’ll also handle the case where the user enters something that isn’t a number.
import java.util.Scanner;
import java.util.InputMismatchException;
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
System.out.print("Enter first number: ");
double num1 = scanner.nextDouble();
System.out.print("Enter second number: ");
double num2 = scanner.nextDouble();
System.out.println("\nSelect operation:");
System.out.println("1. Add");
System.out.println("2. Subtract");
System.out.println("3. Multiply");
System.out.println("4. Divide");
System.out.print("Choice: ");
int choice = scanner.nextInt();
double result;
switch (choice) {
case 1:
result = num1 + num2;
System.out.println(num1 + " + " + num2 + " = " + result);
break;
case 2:
result = num1 - num2;
System.out.println(num1 + " - " + num2 + " = " + result);
break;
case 3:
result = num1 * num2;
System.out.println(num1 + " * " + num2 + " = " + result);
break;
case 4:
if (num2 == 0) {
System.out.println("Error: Cannot divide by zero");
} else {
result = num1 / num2;
System.out.println(num1 + " / " + num2 + " = " + result);
}
break;
default:
System.out.println("Invalid choice. Please select 1-4.");
}
} catch (InputMismatchException e) {
System.out.println("Error: Please enter valid numbers");
}
scanner.close();
}
}
Now invalid input produces helpful messages instead of crashes:
Enter first number: abc
Error: Please enter valid numbers
Enter first number: 10
Enter second number: 0
Select operation:
1. Add
2. Subtract
3. Multiply
4. Divide
Choice: 4
Error: Cannot divide by zero
Stage 4: Continuous Operation
A calculator that quits after one operation isn’t very useful. Let’s add a loop so users can perform multiple calculations.
import java.util.Scanner;
import java.util.InputMismatchException;
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean running = true;
System.out.println("=== Java Calculator ===");
System.out.println("Type 'quit' to exit\n");
while (running) {
try {
System.out.print("Enter first number (or 'quit'): ");
String input = scanner.next();
if (input.equalsIgnoreCase("quit")) {
running = false;
System.out.println("Goodbye!");
continue;
}
double num1 = Double.parseDouble(input);
System.out.print("Enter second number: ");
double num2 = scanner.nextDouble();
System.out.println("Select: 1.Add 2.Subtract 3.Multiply 4.Divide");
System.out.print("Choice: ");
int choice = scanner.nextInt();
calculate(num1, num2, choice);
System.out.println();
} catch (NumberFormatException e) {
System.out.println("Error: Invalid number format\n");
} catch (InputMismatchException e) {
System.out.println("Error: Please enter valid numbers\n");
scanner.nextLine(); // Clear the invalid input
}
}
scanner.close();
}
public static void calculate(double num1, double num2, int operation) {
double result;
switch (operation) {
case 1:
result = num1 + num2;
System.out.println(num1 + " + " + num2 + " = " + result);
break;
case 2:
result = num1 - num2;
System.out.println(num1 + " - " + num2 + " = " + result);
break;
case 3:
result = num1 * num2;
System.out.println(num1 + " * " + num2 + " = " + result);
break;
case 4:
if (num2 == 0) {
System.out.println("Error: Cannot divide by zero");
} else {
result = num1 / num2;
System.out.println(num1 + " / " + num2 + " = " + result);
}
break;
default:
System.out.println("Invalid operation. Choose 1-4.");
}
}
}
Notice we extracted the calculation logic into a separate method. This keeps main() clean and makes the code easier to extend.
Sample session:
=== Java Calculator ===
Type 'quit' to exit
Enter first number (or 'quit'): 100
Enter second number: 25
Select: 1.Add 2.Subtract 3.Multiply 4.Divide
Choice: 4
100.0 / 25.0 = 4.0
Enter first number (or 'quit'): 7
Enter second number: 3
Select: 1.Add 2.Subtract 3.Multiply 4.Divide
Choice: 3
7.0 * 3.0 = 21.0
Enter first number (or 'quit'): quit
Goodbye!
Stage 5: The Complete Calculator
Let’s add a few more features: power and modulo operations, cleaner output formatting, and a memory function to store the last result.
import java.util.Scanner;
import java.util.InputMismatchException;
public class Calculator {
private static double memory = 0;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean running = true;
printWelcome();
while (running) {
try {
System.out.print("\nEnter first number (or 'm' for memory, 'q' to quit): ");
String input = scanner.next();
if (input.equalsIgnoreCase("q")) {
running = false;
System.out.println("Thanks for using Java Calculator!");
continue;
}
double num1;
if (input.equalsIgnoreCase("m")) {
num1 = memory;
System.out.println("Using memory value: " + formatNumber(memory));
} else {
num1 = Double.parseDouble(input);
}
System.out.print("Enter second number (or 'm' for memory): ");
input = scanner.next();
double num2;
if (input.equalsIgnoreCase("m")) {
num2 = memory;
System.out.println("Using memory value: " + formatNumber(memory));
} else {
num2 = Double.parseDouble(input);
}
printOperationMenu();
System.out.print("Choice: ");
int choice = scanner.nextInt();
double result = calculate(num1, num2, choice);
if (!Double.isNaN(result)) {
memory = result;
System.out.println("(Result saved to memory)");
}
} catch (NumberFormatException e) {
System.out.println("Error: Invalid number format");
} catch (InputMismatchException e) {
System.out.println("Error: Please enter valid input");
scanner.nextLine();
}
}
scanner.close();
}
public static void printWelcome() {
System.out.println("╔═══════════════════════════════╗");
System.out.println("║ JAVA CALCULATOR ║");
System.out.println("║ Type 'q' to quit ║");
System.out.println("║ Type 'm' to use memory ║");
System.out.println("╚═══════════════════════════════╝");
}
public static void printOperationMenu() {
System.out.println("\nOperations:");
System.out.println(" 1. Add (+)");
System.out.println(" 2. Subtract (-)");
System.out.println(" 3. Multiply (*)");
System.out.println(" 4. Divide (/)");
System.out.println(" 5. Power (^)");
System.out.println(" 6. Modulo (%)");
}
public static double calculate(double num1, double num2, int operation) {
double result;
String symbol;
switch (operation) {
case 1:
result = num1 + num2;
symbol = "+";
break;
case 2:
result = num1 - num2;
symbol = "-";
break;
case 3:
result = num1 * num2;
symbol = "*";
break;
case 4:
if (num2 == 0) {
System.out.println("Error: Cannot divide by zero");
return Double.NaN;
}
result = num1 / num2;
symbol = "/";
break;
case 5:
result = Math.pow(num1, num2);
symbol = "^";
break;
case 6:
if (num2 == 0) {
System.out.println("Error: Cannot modulo by zero");
return Double.NaN;
}
result = num1 % num2;
symbol = "%";
break;
default:
System.out.println("Invalid operation. Choose 1-6.");
return Double.NaN;
}
System.out.println("\n " + formatNumber(num1) + " " + symbol + " " +
formatNumber(num2) + " = " + formatNumber(result));
return result;
}
public static String formatNumber(double num) {
if (num == (long) num) {
return String.format("%d", (long) num);
} else {
return String.format("%.4f", num).replaceAll("0+$", "").replaceAll("\\.$", "");
}
}
}
The formatNumber() method cleans up output. Instead of showing 5.0 or 3.1400000000, it displays 5 or 3.14.
Full session example:
╔═══════════════════════════════╗
║ JAVA CALCULATOR ║
║ Type 'q' to quit ║
║ Type 'm' to use memory ║
╚═══════════════════════════════╝
Enter first number (or 'm' for memory, 'q' to quit): 2
Enter second number (or 'm' for memory): 10
Operations:
1. Add (+)
2. Subtract (-)
3. Multiply (*)
4. Divide (/)
5. Power (^)
6. Modulo (%)
Choice: 5
2 ^ 10 = 1024
(Result saved to memory)
Enter first number (or 'm' for memory, 'q' to quit): m
Using memory value: 1024
Enter second number (or 'm' for memory): 24
Operations:
1. Add (+)
2. Subtract (-)
3. Multiply (*)
4. Divide (/)
5. Power (^)
6. Modulo (%)
Choice: 2
1024 - 24 = 1000
(Result saved to memory)
Enter first number (or 'm' for memory, 'q' to quit): q
Thanks for using Java Calculator!
What You Practiced
Building this calculator reinforced several concepts:
Variables and data types: Storing numbers, operation choices, and the running flag.
User input with Scanner: Reading different types (double, int, String) and handling the input buffer.
Conditionals: Switch statements for operation selection, if statements for validation.
Loops: While loop for continuous operation until the user quits.
Methods: Breaking code into reusable pieces (calculate, formatNumber, print methods).
Exception handling: Catching invalid input instead of crashing.
Static fields: Using a class variable (memory) to persist data between method calls.
Extensions to Try
Want to keep practicing? Try adding these features:
Square root operation: Add option 7 for calculating the square root of the first number.
Calculation history: Store the last 10 calculations in an ArrayList and let users view them.
Scientific notation: Handle very large or small numbers with proper formatting.
Expression parsing: Accept input like “5 + 3” instead of separate prompts. This is significantly harder and requires string parsing.
GUI version: Once you learn JavaFX or Swing, rebuild this as a graphical application.
Related: Java Variables and Data Types | Java Operators Explained | Java Methods | Getting User Input with Scanner | Java Exception Handling


