JAVA · STEP 1 · INTRO

Java · Intro to the language

Java 25 LTS (any 17+ works): variables, input, conditionals, loops, ArrayLists, HashMaps and methods — each shown first in the JavaScript you know, then in Java.

Step 1 of 5Spring Boot© Arthur Bernier Jrrewritten · verified15 code blocks1009 words

What you will learn#

  • Creating Variables in a New Language
  • Conditionals in a New Language
  • Looping in a New Language
  • Collections in a New Language
  • Writing Functions in a New Language

Getting Started#

Install a current JDK (Java Development Kit). Java 25 is the current long-term-support release (September 2025; the next LTS is 29 in 2027) and everything on this page also runs on Java 17 or 21. Download it from oracle.com/java or the open-source builds at jdk.java.net, then confirm in a terminal:

SH
java -version

Three ways to run Java today, from quickest to most "real":

  • jshell — the REPL that ships with the JDK since Java 9. Type int x = 5; and x * 2, see the answers immediately, /exit to leave.
  • java Main.java — since Java 11 the java launcher compiles and runs a single source file in one step. Perfect for today.
  • javac Main.java && java Main — compile to a .class file, then run it. This is what build tools (Maven, Gradle) do for you in a Spring Boot project.

WHY: Java is compiled and statically typed. The compiler catches a large class of mistakes (wrong type, missing method, misspelled variable) before the program runs — the trade for the extra ceremony you'll notice compared with JavaScript.

If you'd rather not install anything yet, any browser-based Java runner works for today's exercises.

Creating Variables#

How we did it in Javascript

JS
// We create constant variables with the const keywordconst myConstant = 5;// We create re-assignable variables with the let keywordlet myVariable = "Hello World"; // We print variables to the console using console.logconsole.log(myConstant);console.log(myVariable);

How we do this in Java

JAVA
class Main {   // Class-wide constants are static final fields, named in ALL_CAPS by convention  private static final int MY_CONSTANT = 5;   public static void main(String[] args) {    // Every variable has a type, written before the name    String myVariable = "Hello World";    // final makes a local variable single-assignment, like const    final int answer = 42;     System.out.println(MY_CONSTANT);    System.out.println(myVariable + " " + answer);  }}

A few things to notice:

  • Every Java program needs at least one class, and the entry point is public static void main(String[] args). Save this as Main.java — the file name must match the public class.
  • Since Java 10 you can write var myVariable = "Hello World"; for local variables and let the compiler infer the type from the right-hand side. The type is still fixed; var only saves typing.
  • Primitive types (int, double, boolean, char, long) hold values; everything else (String, your classes, collections) is an object reference. Java's String is immutable, like JavaScript's.
  • Semicolons are required.

Receiving Input#

In JavaScript in the browser, input comes from forms or prompt. In Node, reading from the terminal goes through the readline module; the promise-based version reads cleanly with await:

JS
// Node: ask a question in the terminal and wait for the answerimport readline from "node:readline/promises";import { stdin as input, stdout as output } from "node:process"; const rl = readline.createInterface({ input, output });const name = await rl.question("Who are you? ");console.log(`Hey there ${name}!`);rl.close();

How would we do that in Java?

JAVA
import java.util.Scanner;  // Import the Scanner class from java.util class Main {  public static void main(String[] args) {    Scanner scanner = new Scanner(System.in);  // wraps standard input    System.out.print("Who are you? ");     String userName = scanner.nextLine();  // read one line as a String    System.out.println("Hey there " + userName + "!");     System.out.print("How old are you? ");    int age = Integer.parseInt(scanner.nextLine());  // convert text to a number    System.out.println("Next year you'll be " + (age + 1));     scanner.close();  }}

nextLine() always returns a String; convert with Integer.parseInt or Double.parseDouble when you need a number. (Scanner also has nextInt(), but it leaves the newline in the buffer, which trips up the next nextLine() — reading whole lines and parsing is the pattern that doesn't bite.)

Java 25 also finalized a shorter form for small programs: a file containing just void main() { IO.println("Hello"); } runs with java Hello.java, no class or static required. We keep the classic form on these pages because it is what Spring Boot projects use.

Conditionals#

If statements in Javascript

JS
const num = 5; if (num > 3) {  console.log("num is greater than 3");} else if (num > 1) {  console.log("num is greater than 1");} else {  console.log("num is 1 or less");}

If statements in Java

JAVA
class Main {  public static void main(String[] args) {    int num = 5;     // Same shape as JavaScript: parentheses around the condition, braces around the block    if (num > 3) {      System.out.println("num is greater than 3");    } else if (num > 1) {      System.out.println("num is greater than 1");    } else {      System.out.println("num is 1 or less");    }  }}

The syntax is nearly identical, with two differences that matter:

  • The condition must be a real boolean. if (num) is a compile error in Java — there is no truthy/falsy.
  • == compares primitives by value but objects by identity. Compare Strings with .equals(): name.equals("Arthur"), never name == "Arthur".

&&, ||, !, !=, <=, >= and the ternary a ? b : c all work as in JavaScript. There is no === because == never coerces types.

While Loops#

In Javascript

JS
let counter = 0; //This will loop 10 timeswhile (counter < 10) {  console.log(counter);  counter += 1;}

In Java

JAVA
class Main {  public static void main(String[] args) {    int counter = 0;     // this will loop 10 times    while (counter < 10) {      System.out.println(counter);      counter += 1;  // counter++ also works    }  }}

The classic for loop is identical to JavaScript's, and the enhanced for (Java's for…of) walks any array or collection:

JAVA
for (int i = 0; i < 10; i++) {  System.out.println(i);} int[] scores = {90, 85, 72};for (int score : scores) {  System.out.println(score);}

10 Minute Exercise#

Write the code to do the following:

  • Loop 10 times starting the counter at 0
  • On each loop if the counter is even print "it's even"
  • If odd, print "meow" if the number is divisible by 3
  • Otherwise print nothing

Collections#

In Javascript we have arrays and objects

JS
const myArray = [1, 2, 3]; console.log(myArray); //logging the entire arrayconsole.log(myArray[0]); // logging an individual item const myObject = {  cheese: "gouda",  bread: "rye",}; console.log(myObject); //logging the entire objectconsole.log(myObject.cheese); // logging a property using dot notationconsole.log(myObject["bread"]); // logging a property using square bracket notation

In Java we can use ArrayLists and HashMaps

JAVA
import java.util.ArrayList; // a resizable list, the everyday replacement for a JS arrayimport java.util.HashMap;   // key/value pairs, the everyday replacement for a JS objectimport java.util.List;import java.util.Map; class Main {  public static void main(String[] args) {     // Declare with the interface type (List), construct the implementation (ArrayList).    // The <> "diamond" infers the element type from the left-hand side.    List<Integer> myList = new ArrayList<>();     // Add elements to the list    myList.add(1);    myList.add(2);    myList.add(3);     System.out.println(myList);        // printing the whole list: [1, 2, 3]    System.out.println(myList.get(0)); // printing an individual item    System.out.println(myList.size()); // length     // A map from String keys to String values    Map<String, String> myMap = new HashMap<>();     // Add entries to the map    myMap.put("cheese", "gouda");    myMap.put("bread", "rye");     System.out.println(myMap);               // printing the whole map    System.out.println(myMap.get("cheese")); // one value; a missing key returns null    System.out.println(myMap.containsKey("jam")); // false  }}

Collections hold objects, not primitives, so the element type is Integer (the wrapper class), not int; Java boxes and unboxes for you when you add(1) or get(0). There is no dot access for map keys (myMap.cheese is a compile error) — get and put only.

Plain arrays exist too (int[] nums = {1, 2, 3};) but they are fixed-length. For a quick immutable list or map use List.of(1, 2, 3) and Map.of("cheese", "gouda") (Java 9+).

10 Minute Exercise#

Look up the ArrayList methods and apply them to the following list.

JAVA
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
  • How to find a list's length (size())
  • How to loop over a list (for (int n : numbers))
  • How to add and remove items from a list (add, add(index, item), remove(index), remove(Integer.valueOf(7)))

Functions#

in Javascript

JS
const addNums = (x, y) => {  return x + y;}; console.log(addNums(5, 5));

In Java

JAVA
class Main {   // A function is a method on a class; static means it belongs to the class, not an instance.  // The return type (int) comes before the name, and every parameter has a type.  public static int addNums(int x, int y) {    return x + y;  }   // void = returns nothing  public static void sayHello(String name) {    System.out.println("Hello " + name);  }   public static void main(String[] args) {    // Using the methods    System.out.println(addNums(5, 5));    sayHello("Arthur");  }}

There are no standalone functions in Java — every method lives in a class — and no default parameter values. Instead Java lets you overload: define addNums(int, int) and addNums(double, double) side by side and the compiler picks by argument types. Java's arrow functions are lambdas, (x, y) -> x + y, used mostly as arguments to collection methods such as forEach, sort and stream().map.

10 minute exercise#

Write the following methods (Java names are camelCase):

  • subNums that takes two arguments and returns their difference
  • sayHello that takes a name as an argument and says hello to that name
  • sayHelloAdv that takes a Map<String, String> with a name and age key and prints "hello {name}, how does it feel to be {age} years old"
  • looper takes one List<Integer> as an argument, loops over the list and prints each item individually

Resources to Learn More#


See also