```java

```

### Find design problem

```java
public class OrderService {

    private List<Order> orders = new ArrayList<>();

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }
}

```

## Problem 1 - Broken Encapsulation (Most Important)

```java
public List<Order> getOrders() {
    return orders;
}
```

The caller gets direct access to the internal list.

Example

```java
OrderService service = new OrderService();

service.getOrders().clear();

service.getOrders().add(null);

service.getOrders().remove(0);
```

Now the internal state can be modified.

Return an unmodifiable view

```java
public List<Order> getOrders() {
    return Collections.unmodifiableList(orders);
}

or

return List.copyOf(orders);
```

## Problem 2 - Setter Breaks the Object

```java
List<Order> list = new ArrayList<>();

service.setOrders(list);

// Later

list.clear();
```

The service is now empty.

Because both reference the same object.

This is called representation exposure.

Better

Create a defensive copy.

```java
public void setOrders(List<Order> orders) {
    this.orders = new ArrayList<>(orders);
}

```

### Problem 3 - Whole Collection Replacement

Why should a caller replace the entire order list?

```java
service.setOrders(...)
```

Usually a service should expose business operations instead.

```java
addOrder()

removeOrder()

findOrder()

updateOrder()
```

Instead of replacing everything.

### Problem 4 - Violates Encapsulation

The service is exposing its internal data structure.

Clients now know

```
OrderService
    ↓
List
    ↓
ArrayList
```

Tomorrow you may want

- ConcurrentHashMap
- TreeMap
- Database
- Redis

Every client expects a List.

### Problem 5 - Thread Safety

Suppose two threads

Thread A

```java
service.getOrders().add(order);
```

Thread B

```java
service.getOrders().remove(0);
```

ArrayList is not thread-safe.

Possible problems

- lost update
- ConcurrentModificationException
- inconsistent state

### Problem 6 - Null

Someone can write

```java
service.setOrders(null);
```

Later

```java
service.getOrders().size();
```

Boom

NullPointerException

Better

```java
Objects.requireNonNull(orders);
```

### Problem 7 - Business Rules

Suppose duplicate Order IDs are not allowed.

Current design allows

```java
service.getOrders().add(order1);

service.getOrders().add(order1);
```

Service cannot prevent duplicates.

Instead

```java
public void addOrder(Order order)
```

can validate

- duplicate IDs
- status
- customer
- etc.

### Better Design

```java
public class OrderService {

    private final List<Order> orders = new ArrayList<>();

    public List<Order> getOrders() {
        return List.copyOf(orders);
    }

    public void addOrder(Order order) {
        Objects.requireNonNull(order);
        orders.add(order);
    }

    public boolean removeOrder(Order order) {
        return orders.remove(order);
    }

    public Optional<Order> findById(long id) {
        return orders.stream()
                     .filter(o -> o.getId() == id)
                     .findFirst();
    }

}
```

### Even Better

If every order has an ID,

don't use a List.

Use

```java
Map<Long, Order>
```

Then

```
List O(n) vs HashMap O(1)
```

Better Design for Lookup

```java
private final Map<Long, Order> orders = new HashMap<>();
```

Then

```java
addOrder()

removeOrder()

findById()
```

are all much faster.

### SOLID Violations

Current code violates

#### Encapsulation

Clients can change internal state.

#### Information Hiding

Internal implementation is exposed.

#### Single Responsibility

The service acts as

- storage
- data holder
- API

instead of enforcing business behavior.

### Unstructured Concurrency (Traditional Java)

Thread
ExecutorService
CompletableFuture

```java

ExecutorService executor = Executors.newFixedThreadPool(2);

Future<String> user = executor.submit(this::loadUser);
Future<List<Order>> orders = executor.submit(this::loadOrders);

String u = user.get();
List<Order> o = orders.get();

executor.shutdown();

```

Threads can outlive the method that created them.
Cancellation is manual.
Error handling is complicated.
Thread leaks are possible.

### Structured Concurrency (Java 21+ Preview)

### StructuredTaskScope

The lifetime of child threads is tied to the parent scope.

```java

try (var scope =
    new StructuredTaskScope.ShutdownOnFailure()) {

    var user =
            scope.fork(this::loadUser);

    var orders =
            scope.fork(this::loadOrders);

    scope.join();
    scope.throwIfFailed();

    return new Result(
            user.get(),
            orders.get());

}


```

### Automatic Cancellation

If Task 1 throws an exception,

Structured Concurrency automatically Task 2 as well

### Structured Concurrency + Virtual Threads

#### This is the intended combination in modern Java.

```java

try (var scope =
new StructuredTaskScope.ShutdownOnFailure()) {

    scope.fork(() -> serviceA());

    scope.fork(() -> serviceB());

    scope.join();

}
```

Each fork() typically runs on a Virtual Thread.

Benefits:

- Millions of lightweight threads.
- Automatic lifecycle management.
- Simpler code than CompletableFuture.

```java
Function<String, Integer> length = s -> s.length();

System.out.println(length.apply("Hello"));

List<String> list =
        List.of("Java", "Spring", "AI", "Kubernetes");

list.stream()
    .sorted(Comparator.comparingInt(String::length))
    .forEach(System.out::println);


AI
Java
Spring
Kubernetes

List<Integer> lengths =
        list.stream()
            .map(String::length)
            .toList();

System.out.println(lengths);

[4, 6, 2]


@FunctionalInterface
interface LengthCalculator {
    int length(String s);
}

LengthCalculator calc = s -> s.length();

System.out.println(calc.length("ChatGPT"));
```

### var (Local Variable Type Inference) Java 10

```java

String name = "Saravanan";

List<String> names = new ArrayList<>();

Map<String, List<Employee>> map = new HashMap<>();



var name = "Saravanan";

var names = new ArrayList<String>();

var map = new HashMap<String, List<Employee>>();

// The compiler converts them to

String name = "Saravanan";

ArrayList<String> names = new ArrayList<>();

HashMap<String, List<Employee>> map =
        new HashMap<>();

Notice that var becomes the actual concrete type (ArrayList, HashMap), not the interface (List, Map).

```

### Works with Streams

```java


// Without var

Map.Entry<String,Integer> entry =
map.entrySet().iterator().next();

// With var

var entry =
map.entrySet().iterator().next();

```

### When should you be careful?

### 1. Type is not obvious (Bad)

```java
    var x = calculate();
```

What is x?

- int?
- String?
- Employee?
- List?

nobody knows without running calculate

### 5. Null

Illegal

```java
var x = null;
var x;

class Person {

    var name = "John";
    // var works only for local variables.
}

public var getName() {
}

void test(var name)

```

Compiler error

## Structural and non-structional modifications

### in java collections

```java


List<String> list = new ArrayList<>();

list.add("Java");      // Structural
list.add("Spring");    // Structural
list.remove("Java");   // Structural
list.clear();          // Structural

```

### What is a Non-Structural Modification?

#### A non-structural modification changes only the contents of an existing element without changing the collection's size.

```java

List<String> list = new ArrayList<>();

list.add("Java");
list.add("Spring");

list.set(1, "Spring Boot");

Before = 2
After  = 2


List<String> list =
new ArrayList<>();

list.add("A");
list.add("B");
list.add("C");

Iterator<String> it = list.iterator();

// The iterator was created before the modification.

list.add("D");

it.next();  // throws ConcurrentModificationException


// Because ArrayList maintains a field called
// modCount
// Every structural modification increments it.

// In hashmap

map.put("A",1);
// If key doesn't exist, then structural

map.put("A",100);
// If key already exists, then non-structural

map.remove("A");
// structural

map.clear();
// structural


for(String s : list){

    list.remove(s); // throws ConcurrentModificationException
}

Iterator<String> it =
        list.iterator();

while(it.hasNext()){

    String s = it.next();

    if(s.equals("Java")){

        it.remove(); // this will work
    }
}



Operation	            Structural?

add()	                    ✅ Yes
remove()	                ✅ Yes
clear()	                    ✅ Yes
put(new key)	            ✅ Yes
remove(key)	                ✅ Yes
set(index,value)	        ❌ No
put(existing key,new value)	❌ No
replace()	                ❌ No


```
