Everything you need before reading the HOTW code


Table of Contents

  1. What is Java?
  2. Your First Java File
  3. Variables and Data Types
  4. Classes and Objects
  5. Methods (Functions)
  6. Access Modifiers
  7. Constructors
  8. The this Keyword
  9. Static vs Instance
  10. Packages and Imports
  11. Collections β€” List and Map
  12. null and Null Checks
  13. The final Keyword
  14. boolean and Conditions
  15. Loops

1. What is Java?

Java is a compiled, object-oriented programming language. It runs on the JVM (Java Virtual Machine), which means the same code runs on Windows, Linux, or Mac.

You write .java files
  β†’ Java compiler converts to .class files (bytecode)
    β†’ JVM runs bytecode on any operating system

Java vs JavaScript vs Python

Feature Java JavaScript Python
Type system Static (declare types) Dynamic Dynamic
Speed Fast Medium Slower
Use case Backend, Android, AWS Lambda Frontend, Node.js Data science, scripts
Amazon backend βœ… Used heavily Used for Node.js Used for ML

2. Your First Java File

Every Java program starts with a class. The file name MUST match the class name.

// File: HelloWorld.java

public class HelloWorld {              // Class definition
    
    public static void main(String[] args) {  // Entry point
        System.out.println("Hello World!");   // Print to console
    }
}

Breaking it down:

Part What it means
public Anyone can access this
class We are defining a blueprint
HelloWorld Name of the class (matches filename)
static Belongs to class, not an object
void This method returns nothing
main Special method β€” Java runs this first
String[] args Command-line arguments (ignore for now)
System.out.println(...) Print something + new line

3. Variables and Data Types

Variables are boxes that hold data. In Java, you must say what TYPE of data the box holds.

// Primitive types (simple values)
int age = 25;               // whole numbers: -2 billion to +2 billion
double price = 19.99;       // decimal numbers (64-bit precision)
float ratio = 1.5f;         // decimal numbers (32-bit, less precise)
boolean isActive = true;    // true or false only
char letter = 'A';          // single character

// Reference types (objects)
String name = "FleetX1-NA"; // text (technically an Object in Java)
Integer count = 100;        // wrapped int (can be null, used in generics)
Double factor = 2.5;        // wrapped double (can be null)

The difference between int and Integer:

int x = 5;         // primitive β€” cannot be null, faster
Integer y = 5;     // object β€” CAN be null, used in Lists/Maps

Integer z = null;  // βœ… valid β€” object can be null
int w = null;      // ❌ ERROR β€” primitive cannot be null

In the HOTW code, you’ll see Integer hostNeeded (with capital I) because it can be null when fleet data is missing.


4. Classes and Objects

A class is a blueprint. An object is a thing made from that blueprint.

// BLUEPRINT: defines what a Car looks like
class Car {
    String color;     // field (property)
    int speed;        // field (property)
    
    void accelerate() {   // method (behavior)
        speed = speed + 10;
    }
}

// OBJECTS: actual cars made from the blueprint
Car myCar = new Car();     // create an object
myCar.color = "Red";       // set a field
myCar.accelerate();        // call a method

Relating to HOTW code:

// HOTWHelperModel is a CLASS (blueprint)
public class HOTWHelperModel {
    private Integer hostNeeded;    // field
    private Service service;       // field (another object!)
    private Fleet fleet;           // field
}

// In HotwUpscalingHelper, we CREATE an OBJECT of HOTWHelperModel:
HOTWHelperModel model = new HOTWHelperModel();

5. Methods (Functions)

Methods are actions a class can perform. They can take input (parameters) and give back output (return value).

//     return type   name      parameters
public int          add   (int a, int b) {
    return a + b;   // send back the result
}

// Calling it:
int result = add(3, 5);  // result = 8

Method syntax breakdown:

[access modifier] [return type] [method name] ([parameters]) {
    // body
    return [value];  // if return type is not void
}

void means no return:

public void printMessage(String msg) {  // void = returns nothing
    System.out.println(msg);
    // no return statement needed
}

From the HOTW code β€” validateFleetData method:

// This method takes a Fleet object as input
// and returns nothing (void)
// but throws an error if data is invalid
private void validateFleetData(Fleet fleet) {
    if (fleet == null || fleet.getFleetProjection() == null) {
        throw new IllegalArgumentException("Invalid fleet data...");
    }
}

6. Access Modifiers

Access modifiers control who can use a field or method.

Modifier Who can access
public Anyone, anywhere
private Only inside this class
protected This class + subclasses
(none) Same package only
public class BankAccount {
    private double balance;    // only THIS class can touch balance
    
    public void deposit(double amount) {    // anyone can call deposit
        balance = balance + amount;         // but can only change balance here
    }
    
    public double getBalance() {           // read-only access
        return balance;
    }
}

In HOTW code, almost all fields are private. You access them via getXxx() methods (getters).


7. Constructors

A constructor is a special method called when you create an object. It has the SAME name as the class.

public class Fleet {
    private String fleetId;
    private String serviceId;
    
    // Constructor
    public Fleet(String fleetId, String serviceId) {
        this.fleetId = fleetId;
        this.serviceId = serviceId;
    }
}

// Using it:
Fleet myFleet = new Fleet("FORTRESSService-X1-NA", "FORTRESSService");
//                        ↑ passed to fleetId      ↑ passed to serviceId

Constructor vs Method:

Constructor Method
Name Same as class Any name
Return type None (not even void) Has return type
Purpose Initialize an object Perform an action
Called When using new Explicitly

In HOTW code, HotwUpscalingHelper has a constructor that takes Context context. This sets up all dependencies.


8. The this Keyword

this refers to the current object. Used when parameter names clash with field names.

public class Person {
    private String name;   // field named "name"
    
    public Person(String name) {       // parameter also named "name"
        this.name = name;              // "this.name" = field
                                       // "name" alone = parameter
    }
}

Without this:

public Person(String name) {
    name = name;   // ❌ WRONG! Assigns parameter to itself, field stays null
}

With this:

public Person(String name) {
    this.name = name;   // βœ… CORRECT! Sets the object's field
}

9. Static vs Instance

Static:

  • Belongs to the CLASS itself
  • You DON’T need to create an object
  • Shared across all objects

Instance:

  • Belongs to a specific object
  • You need to create an object first
public class MathHelper {
    
    // STATIC method β€” call without creating object
    public static int square(int n) {
        return n * n;
    }
    
    // INSTANCE method β€” need to create object first
    public String getDescription() {
        return "I am a MathHelper";
    }
}

// Using static:
int result = MathHelper.square(5);   // no 'new' needed!

// Using instance:
MathHelper helper = new MathHelper();  // must create object
String desc = helper.getDescription(); // then call method

From HOTW code β€” Static Factory Methods:

// In EPICBackendHotwApiCallsCommon.java:
public static EPICBackendHotwApiCallsCommon getInstance(
    EPICBackendApiProxy proxy, LambdaLogger logger) {
    return new EPICBackendHotwApiCallsCommon(proxy, logger);
}

// Usage β€” no 'new' needed:
EPICBackendHotwApiCallsCommon apiCalls =
    EPICBackendHotwApiCallsCommon.getInstance(proxy, logger);

10. Packages and Imports

A package is a folder/namespace that organizes classes. Like folders on your computer.

// Top of every Java file declares its package:
package com.amazon.epicbackendtriggers.lambda.HotwHelper;
//        ↑company  ↑project              ↑folder path

This means the file is at:

src/
└── com/
    └── amazon/
        └── epicbackendtriggers/
            └── lambda/
                └── HotwHelper/
                    └── HotwUpscalingHelper.java

Import = use classes from other packages:

// You need to "import" classes from other packages to use them
import java.util.List;          // from Java's standard library
import java.util.Map;           // from Java's standard library
import java.util.ArrayList;     // from Java's standard library

// OR import everything from a package with wildcard:
import java.util.*;             // imports ALL from java.util

// Amazon/EPIC internal imports:
import com.amazon.epicbackendtriggers.lambda.model.fleet.Fleet;

In HotwUpscalingHelper.java, there are ~50 import lines! Each one brings in a class from another package.


11. Collections β€” List and Map

List β€” an ordered collection (like an array but flexible size):

import java.util.List;
import java.util.ArrayList;

// Create a list of strings
List<String> names = new ArrayList<>();

// Add items
names.add("FleetA");
names.add("FleetB");
names.add("FleetC");

// Get item at index (0-based)
String first = names.get(0);   // "FleetA"
String last  = names.get(2);   // "FleetC"

// Size
int size = names.size();       // 3

// Check if empty
boolean empty = names.isEmpty();  // false

// Loop through
for (String name : names) {
    System.out.println(name);   // prints each one
}

Map β€” key-value pairs (like a dictionary):

import java.util.Map;
import java.util.HashMap;

// Map where key=String, value=Integer
Map<String, Integer> fleetHostCount = new HashMap<>();

// Add entries
fleetHostCount.put("FleetA-NA", 100);
fleetHostCount.put("FleetB-EU", 200);
fleetHostCount.put("FleetC-FE", 150);

// Get value by key
int count = fleetHostCount.get("FleetA-NA");   // 100

// Check if key exists
boolean has = fleetHostCount.containsKey("FleetA-NA");  // true

// Loop through key-value pairs
for (Map.Entry<String, Integer> entry : fleetHostCount.entrySet()) {
    String fleet = entry.getKey();
    Integer hosts = entry.getValue();
    System.out.println(fleet + " needs " + hosts + " hosts");
}

From HOTW code:

// In HotwUpscalingHelper.java:
Map<String, ArrayList<String>> hostTypeWithAsg = new HashMap<>();
//   ↑ hostType         ↑ list of ASG names for that host type

Map<String, Integer> asgToHostRecommendationMap = new HashMap<>();
//   ↑ ASG tag          ↑ how many hosts to order for that ASG

12. null and Null Checks

null means β€œno value” / β€œnothing here”. Any object can be null.

String name = null;   // name has no value

// If you try to use it WITHOUT checking first:
int length = name.length();   // ❌ NullPointerException β€” CRASH!

// ALWAYS check before using:
if (name != null) {
    int length = name.length();   // βœ… safe
}

// Modern way β€” Objects.isNull():
if (Objects.isNull(name)) {
    System.out.println("name is null");
}

From HOTW code β€” null checks:

// validateFleetData checks for null in many places:
if (fleet == null                               // fleet object itself null?
    || fleet.getFleetProjection() == null       // array null?
    || fleet.getFleetProjection().length == 0   // array empty?
    || fleet.getFleetProjection()[0] == null    // first element null?
    || fleet.getFleetConfiguration() == null) { // config null?
    
    throw new IllegalArgumentException("Invalid fleet data...");
}

13. The final Keyword

final means cannot be changed after assignment.

// Final variable β€” value locked forever
final int MAX_HOSTS = 1000;
MAX_HOSTS = 2000;   // ❌ ERROR: cannot reassign final variable

// Final class β€” cannot be extended (subclassed)
public final class TableConstants {
    public static final String FLEET_ID = "Fleet Id";
    //                 ↑ static final = a CONSTANT
}

// Using it:
String colName = TableConstants.FLEET_ID;   // "Fleet Id"

In TableConstants.java, ALL fields are public static final String. This is the standard Java way to define constants.


14. boolean and Conditions

boolean isReady = true;
boolean hasFailed = false;

// if-else
if (isReady) {
    System.out.println("Fleet is ready!");
} else {
    System.out.println("Fleet not ready");
}

// Comparison operators
int a = 5, b = 10;
boolean eq = (a == b);   // false β€” equal?
boolean ne = (a != b);   // true  β€” not equal?
boolean lt = (a < b);    // true  β€” less than?
boolean gt = (a > b);    // false β€” greater than?
boolean le = (a <= b);   // true  β€” less than or equal?
boolean ge = (a >= b);   // false β€” greater than or equal?

// Logical operators
boolean both = (a < 10 && b > 5);   // AND β€” both must be true
boolean either = (a > 10 || b > 5); // OR  β€” at least one true
boolean notThis = !(a == b);         // NOT β€” flip true/false

Ternary operator (shorthand if-else):

// Long way:
String status;
if (isReady) {
    status = "Ready";
} else {
    status = "Not Ready";
}

// Short way (ternary):
String status = isReady ? "Ready" : "Not Ready";
//                      ↑ if true   ↑ if false

From HOTW code β€” ternary in status determination:

// In HotwUpscalingHelper.java:
String hotwExecutionStatus =
    asgHOTWExecutionStatus.values().stream().allMatch(Boolean.TRUE::equals)
        ? HotwExecutionAllDetailsInput.StatusOfHOTW.SUCCESS.getStatus()
        : asgHOTWExecutionStatus.values().stream().anyMatch(Boolean.TRUE::equals)
            ? HotwExecutionAllDetailsInput.StatusOfHOTW.PARTIAL_SUCCESS.getStatus()
            : HotwExecutionAllDetailsInput.StatusOfHOTW.FAIL.getStatus();

Translation:

  • If ALL ASGs succeeded β†’ status = β€œSuccess”
  • Else if ANY ASG succeeded β†’ status = β€œPartialSuccess”
  • Else β†’ status = β€œFail”

15. Loops

For loop β€” when you know the count:

for (int i = 0; i < 5; i++) {
    System.out.println("Count: " + i);
}
// Prints: 0, 1, 2, 3, 4

Enhanced for loop (for-each) β€” iterate over a collection:

List<String> fleets = List.of("FleetA", "FleetB", "FleetC");

for (String fleet : fleets) {   // "for each fleet in fleets"
    System.out.println(fleet);
}

While loop β€” keep going until condition is false:

int hostsToDescale = 10;

while (hostsToDescale > 0) {
    // reduce one host from biggest ASG
    hostsToDescale--;
}

From HOTW code β€” while loop in descaling:

// DescaleHostRecommendationHelper.java:
while (descaleHosts > 0) {
    String maxKey = "";
    int maxValue = 0;
    
    // Find the ASG with the most hosts
    for (Map.Entry<String, Integer> asgCountEntry : asgWithCount.entrySet()) {
        if (asgCountEntry.getValue() > maxValue) {
            maxValue = asgCountEntry.getValue();
            maxKey = asgCountEntry.getKey();
        }
    }
    
    if (maxValue == 0 && descaleHosts > 0) {
        break;   // exit the while loop
    }
    
    asgWithCount.put(maxKey, asgWithCount.get(maxKey) - 1);
    descaleHosts--;
}

This algorithm: β€œRemove hosts one-by-one from the ASG that has the most hosts β€” to keep it balanced.”


🎯 Layer 1 Summary

Concept What you learned
Java file structure package + class + methods
Variables int, String, boolean, double, Integer
Classes Blueprints for objects
Objects Instances created with new
Methods Functions that belong to a class
Access modifiers public, private, protected
static Belongs to class, no object needed
final Cannot be changed β€” used for constants
Collections List<T> for ordered items, Map<K,V> for key-value
null No value β€” always check before using!
Loops for, for-each, while

β†’ Continue to Layer 2: Java Intermediate