Java Collections Framework: Complete Guide with Examples

The Java Collections Framework is essential for every Java developer. Here’s a comprehensive guide. Collection Hierarchy Collection ├── List │ ├── ArrayList │ ├── LinkedList │ └── Vector ├── Set │ ├── HashSet │ ├── LinkedHashSet │ └── TreeSet └── Queue ├── PriorityQueue └── Deque └── ArrayDeque Lists ArrayList List<String> list = new ArrayList<>(); list.add("Java"); list.add("Python"); list.get(0); // "Java" list.remove(0); LinkedList List<String> list = new LinkedList<>(); list.add("First"); list.add("Last"); // Better for frequent insertions/deletions Sets HashSet Set<String> set = new HashSet<>(); set.add("Java"); set.add("Java"); // Duplicate ignored set.contains("Java"); // true TreeSet Set<String> set = new TreeSet<>(); set.add("Zebra"); set.add("Apple"); // Automatically sorted: [Apple, Zebra] Maps Map<String, Integer> map = new HashMap<>(); map.put("Java", 1); map.put("Python", 2); map.get("Java"); // 1 map.containsKey("Java"); // true Best Practices Use ArrayList for random access Use LinkedList for frequent insertions Use HashSet for unique elements Use TreeSet for sorted unique elements Use HashMap for key-value pairs Conclusion Master Java Collections to write efficient code! 📚

December 15, 2023 · 4160 views

Solving the N+1 Problem in Spring Data JPA

The N+1 problem is a common performance issue in JPA. Here’s how to solve it in Spring Data JPA. Understanding N+1 Problem // N+1 queries: 1 for users + N for each user's posts List<User> users = userRepository.findAll(); for (User user : users) { List<Post> posts = postRepository.findByUserId(user.getId()); // N queries } Solutions 1. Eager Fetching @Entity public class User { @OneToMany(fetch = FetchType.EAGER) private List<Post> posts; } 2. Join Fetch (JPQL) @Query("SELECT u FROM User u JOIN FETCH u.posts") List<User> findAllWithPosts(); 3. Entity Graphs @EntityGraph(attributePaths = {"posts"}) @Query("SELECT u FROM User u") List<User> findAllWithPosts(); 4. Batch Fetching @Entity public class User { @BatchSize(size = 10) @OneToMany(fetch = FetchType.LAZY) private List<Post> posts; } Best Practices Use lazy loading by default Fetch associations when needed Use entity graphs Monitor query performance Use DTO projections Conclusion Solve N+1 problems with: ...

November 20, 2023 · 4431 views

Spring WebFlux: When to Use It and How to Build With It

Spring WebFlux enables reactive programming in Spring. Here’s when and how to use it. When to Use WebFlux Use WebFlux When: High concurrency requirements Non-blocking I/O needed Streaming data Microservices with reactive backends Use MVC When: Traditional request-response Blocking operations Existing Spring MVC codebase Simpler mental model needed Basic Setup Dependencies <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> Reactive Controller @RestController public class UserController { @GetMapping("/users") public Flux<User> getUsers() { return userService.findAll(); } @GetMapping("/users/{id}") public Mono<User> getUser(@PathVariable Long id) { return userService.findById(id); } @PostMapping("/users") public Mono<User> createUser(@RequestBody Mono<User> user) { return userService.save(user); } } Reactive Types Mono // Single value or empty Mono<String> mono = Mono.just("Hello"); Mono<String> empty = Mono.empty(); Mono<String> error = Mono.error(new RuntimeException()); Flux // Multiple values Flux<String> flux = Flux.just("A", "B", "C"); Flux<Integer> range = Flux.range(1, 10); Reactive Repository public interface UserRepository extends ReactiveCrudRepository<User, Long> { Flux<User> findByStatus(String status); Mono<User> findByEmail(String email); } Error Handling @GetMapping("/users/{id}") public Mono<User> getUser(@PathVariable Long id) { return userService.findById(id) .switchIfEmpty(Mono.error(new UserNotFoundException())) .onErrorResume(error -> { // Handle error return Mono.empty(); }); } Testing @SpringBootTest @AutoConfigureWebTestClient class UserControllerTest { @Autowired private WebTestClient webTestClient; @Test void shouldGetUsers() { webTestClient.get() .uri("/users") .exchange() .expectStatus().isOk() .expectBodyList(User.class); } } Best Practices Use reactive types throughout Avoid blocking operations Handle errors properly Use backpressure Monitor performance Conclusion Spring WebFlux provides: ...

October 15, 2023 · 4379 views

Java Evolution: From Java 8 to Java 25 - Complete Guide

Java has evolved significantly from Java 8 to Java 25. Here’s a comprehensive guide to the major changes. Java 8 (2014) Lambda Expressions List<String> names = Arrays.asList("Java", "Python"); names.forEach(name -> System.out.println(name)); Streams API List<String> filtered = names.stream() .filter(name -> name.startsWith("J")) .collect(Collectors.toList()); Optional Optional<String> name = Optional.of("Java"); name.ifPresent(System.out::println); Java 9 (2017) Modules module com.example { requires java.base; exports com.example.api; } Private Methods in Interfaces interface MyInterface { default void method() { helper(); } private void helper() { // Private method } } Java 11 (2018) String Methods String text = " Java "; text.strip(); // "Java" text.repeat(3); // " Java Java Java " HTTP Client HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.example.com")) .build(); Java 17 (2021) Sealed Classes public sealed class Shape permits Circle, Rectangle { } public final class Circle extends Shape { } Pattern Matching if (obj instanceof String s) { System.out.println(s.length()); } Java 21 (2023) Virtual Threads Thread.ofVirtual().start(() -> { // Lightweight thread }); Pattern Matching for Switch String result = switch (value) { case Integer i -> "Integer: " + i; case String s -> "String: " + s; default -> "Unknown"; }; Java 25 (2025) Latest Features Enhanced pattern matching Improved performance Better memory management New API additions Migration Guide Update dependencies Test thoroughly Use new features gradually Monitor performance Update tooling Conclusion Java continues to evolve with: ...

September 10, 2023 · 3596 views

SOLID Principles Explained with Java Examples

SOLID principles are fundamental to object-oriented design. Here’s how to apply them in Java. S - Single Responsibility Principle Bad class User { public void save() { } public void sendEmail() { } public void generateReport() { } } Good class User { // Only user data } class UserRepository { public void save(User user) { } } class EmailService { public void sendEmail(User user) { } } O - Open/Closed Principle Bad class AreaCalculator { public double calculateArea(Object shape) { if (shape instanceof Circle) { // Calculate circle area } else if (shape instanceof Rectangle) { // Calculate rectangle area } } } Good interface Shape { double calculateArea(); } class Circle implements Shape { public double calculateArea() { return Math.PI * radius * radius; } } class Rectangle implements Shape { public double calculateArea() { return width * height; } } L - Liskov Substitution Principle Bad class Bird { public void fly() { } } class Penguin extends Bird { public void fly() { throw new UnsupportedOperationException(); } } Good interface Bird { void eat(); } interface FlyingBird extends Bird { void fly(); } class Sparrow implements FlyingBird { public void fly() { } } class Penguin implements Bird { // No fly method } I - Interface Segregation Principle Bad interface Worker { void work(); void eat(); void sleep(); } class Robot implements Worker { public void eat() { } // Not applicable public void sleep() { } // Not applicable } Good interface Workable { void work(); } interface Eatable { void eat(); } class Human implements Workable, Eatable { public void work() { } public void eat() { } } class Robot implements Workable { public void work() { } } D - Dependency Inversion Principle Bad class UserService { private MySQLDatabase database; public UserService() { this.database = new MySQLDatabase(); } } Good interface Database { void save(User user); } class UserService { private Database database; public UserService(Database database) { this.database = database; } } Conclusion SOLID principles help you write: ...

August 15, 2023 · 4126 views

Java Isn't Verbose - You Are: Writing Concise Java Code

Java is often criticized for verbosity, but modern Java can be concise. Here’s how to write cleaner code. Modern Java Features Records (Java 14+) // Old way public class User { private String name; private String email; public User(String name, String email) { this.name = name; this.email = email; } // Getters, equals, hashCode, toString... } // New way public record User(String name, String email) { } Pattern Matching (Java 17+) // Old way if (obj instanceof String) { String s = (String) obj; System.out.println(s.length()); } // New way if (obj instanceof String s) { System.out.println(s.length()); } Switch Expressions (Java 14+) // Old way String result; switch (day) { case MONDAY: case FRIDAY: result = "Weekday"; break; default: result = "Weekend"; } // New way String result = switch (day) { case MONDAY, FRIDAY -> "Weekday"; default -> "Weekend"; }; Best Practices Use Streams // Old way List<String> filtered = new ArrayList<>(); for (String name : names) { if (name.startsWith("J")) { filtered.add(name.toUpperCase()); } } // New way List<String> filtered = names.stream() .filter(name -> name.startsWith("J")) .map(String::toUpperCase) .toList(); Use Optional // Old way String result = null; if (user != null && user.getName() != null) { result = user.getName().toUpperCase(); } // New way String result = Optional.ofNullable(user) .map(User::getName) .map(String::toUpperCase) .orElse(null); Conclusion Modern Java is concise when you: ...

July 20, 2023 · 4015 views

Spring Boot Validation: Complete Guide with @Valid and @Validated

Validation is crucial in Spring Boot applications. Here’s a complete guide to using @Valid and @Validated. Basic Validation Dependencies <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> Bean Validation public class CreateUserRequest { @NotBlank(message = "Name is required") private String name; @Email(message = "Invalid email format") @NotBlank private String email; @Min(value = 18, message = "Age must be at least 18") @Max(value = 120, message = "Age must be at most 120") private Integer age; } @Valid vs @Validated @Valid @PostMapping("/users") public ResponseEntity<User> createUser(@Valid @RequestBody CreateUserRequest request) { // Validates request object } @Validated @RestController @Validated public class UserController { @GetMapping("/users/{id}") public User getUser(@PathVariable @Min(1) Long id) { // Validates path variable } } Custom Validators @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = PhoneNumberValidator.class) public @interface PhoneNumber { String message() default "Invalid phone number"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } public class PhoneNumberValidator implements ConstraintValidator<PhoneNumber, String> { @Override public boolean isValid(String value, ConstraintValidatorContext context) { return value != null && value.matches("^\\+?[1-9]\\d{1,14}$"); } } Validation Groups public interface CreateGroup {} public interface UpdateGroup {} public class UserRequest { @NotNull(groups = UpdateGroup.class) private Long id; @NotBlank(groups = {CreateGroup.class, UpdateGroup.class}) private String name; } @PostMapping("/users") public ResponseEntity<User> create(@Validated(CreateGroup.class) @RequestBody UserRequest request) { // Only validates CreateGroup fields } Error Handling @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<ErrorResponse> handleValidation( MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getFieldErrors().forEach(error -> errors.put(error.getField(), error.getDefaultMessage()) ); return ResponseEntity.badRequest() .body(new ErrorResponse("Validation failed", errors)); } } Best Practices Validate at controller level Use appropriate annotations Create custom validators Handle validation errors Use validation groups Conclusion Spring Boot validation provides: ...

June 10, 2023 · 3818 views