Java and Spring Boot · Beginner
Modern Java in one program
Why it matters
Java appeared in more than half of the Software Engineer job descriptions we read, and in three quarters of the junior ones. Much older Java code is verbose; modern Java is compact and safer. Knowing both styles, and preferring the modern one, is what reviewers and interviewers look for.
The concept
Records are immutable data carriers:
record Order(String id, BigDecimal amount) {}gives you a constructor, accessors (order.id()),equals,hashCodeandtoString. A compact constructor can validate fields.Enums represent a fixed set of values, and the compiler checks that a
switchcovers them all.Collections:
List.of,Map.ofcreate immutable collections.ArrayList,HashMapandTreeMap(sorted keys) are the everyday mutable ones.Streams express transformations:
filter,map,collect,groupingBy. Use them for clear pipelines and plain loops when a loop is clearer.Optional makes "may be missing" explicit in return types, instead of returning
null.BigDecimal for money.
doublecannot represent most decimal amounts exactly.Exceptions: throw
IllegalArgumentExceptionfor bad input; catch only what you can handle.
Worked example: orders
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.*;
public class Orders {
enum Status { PLACED, SHIPPED, DELIVERED, CANCELLED }
record Order(String id, String city, Status status, BigDecimal amount) {
Order {
if (amount.signum() < 0) throw new IllegalArgumentException("amount must not be negative");
}
}
static Optional<Order> largest(List<Order> orders, String city) {
return orders.stream()
.filter(o -> o.city().equals(city))
.max(Comparator.comparing(Order::amount));
}
public static void main(String[] args) {
List<Order> orders = List.of(
new Order("A1", "Pune", Status.DELIVERED, new BigDecimal("1250.00")),
new Order("A2", "Delhi", Status.CANCELLED, new BigDecimal("499.00")),
new Order("A3", "Pune", Status.SHIPPED, new BigDecimal("3100.50")),
new Order("A4", "Delhi", Status.DELIVERED, new BigDecimal("780.00")));
Map<String, BigDecimal> revenueByCity = orders.stream()
.filter(o -> o.status() != Status.CANCELLED)
.collect(Collectors.groupingBy(Order::city, TreeMap::new,
Collectors.reducing(BigDecimal.ZERO, Order::amount, BigDecimal::add)));
System.out.println(revenueByCity);
System.out.println(largest(orders, "Pune").map(Order::id).orElse("none"));
System.out.println(largest(orders, "Mumbai").map(Order::id).orElse("none"));
String label = switch (orders.get(1).status()) {
case PLACED, SHIPPED -> "in progress";
case DELIVERED -> "done";
case CANCELLED -> "cancelled";
};
System.out.println(label);
try {
new Order("A5", "Pune", Status.PLACED, new BigDecimal("-1"));
} catch (IllegalArgumentException e) {
System.out.println("rejected: " + e.getMessage());
}
}
}Java 11 and later can run a single source file directly:
$ java Orders.java
{Delhi=780.00, Pune=4350.50}
A3
none
cancelled
rejected: amount must not be negativePoints to notice:
groupingBywithTreeMap::newgives a sorted map, so the output order is stable.BigDecimalkeeps amounts exact. Withdouble,0.1 + 0.2is0.30000000000000004, and such errors add up in totals.largestreturnsOptional<Order>, so the caller must decide what "not found" means (orElse("none")).The
switchexpression has nodefault. If someone adds a new status, the compiler reports the missing case.
Common mistakes
Comparing strings or
BigDecimalwith==. Useequalsfor strings, andcompareToforBigDecimal(new BigDecimal("1.0").equals(new BigDecimal("1.00"))is false).Returning
nullfor "not found". ReturnOptionalor an empty collection.Mutating shared collections.
List.ofis immutable; copy into a newArrayListif you need to change it.Catching
Exceptioneverywhere. Catch specific exceptions where you can recover, and let the rest propagate.
Interview angle
Common questions: the difference between == and equals, why hashCode must be consistent with equals, ArrayList versus LinkedList, how HashMap works (buckets, hashing, resizing), checked versus unchecked exceptions, and what records and Optional are for. Be ready to write a stream pipeline and then the same logic as a loop.
Practice task
Add a
LocalDate placedOnfield and print revenue per month for delivered orders.Write a method that returns the top two cities by number of non-cancelled orders, first with streams and then with a loop.