# Io / Github / Biezhi / Java11 / Collections

## Overview

This package demonstrates collection-related features introduced across JDK 7 through 11, specifically:

- **Diamond operator (`<>`) with anonymous inner classes** — an ergonomic improvement that began in Java 7 and was refined in Java 9 so that anonymous subclasses can use the diamond operator with explicit or wildcard type parameters.
- **Collection factory methods** (`List.of`, `Map.of`, `Set.of`, `Map.ofEntries`, `Map.entry`) — immutable collections API introduced in Java 9 that eliminates the old `Arrays.asList(...)` and `Collections.unmodifiableMap(...)` boilerplate.

Together, these two examples serve as a quick reference for modern Java collection idioms in a JDK 11 codebase.

## Key Classes and Interfaces

### `Example`

**Source:** [src/main/java/io/github/biezhi/java11/collections/Example.java](src/main/java/io/github/biezhi/java11/collections/Example.java)

This class is a standalone demo (driven entirely from `main`) that showcases every factory method added to the core `List`, `Map`, and `Set` interfaces since Java 9.

#### What it demonstrates

| Factory method | JDK version | Returns | Example from code |
|---|---|---|---|
| `List.of()` | 9 | Empty `List<Object>` | `List immutableList = List.of();` |
| `List.of(T... elements)` | 9 | Immutable `List<T>` | `var foo = List.of("biezhi", "github", "...");` |
| `Map.of()` | 9 | Empty `Map<Object,Object>` | `Map emptyImmutableMap = Map.of();` |
| `Map.of(k1,v1, k2,v2, ...)` | 9–10 (varargs in 11) | Immutable `Map<K,V>` | `Map mmp = Map.of(2017, "...", 2018, "...");` |
| `Map.ofEntries(entry(...), ...)` | 9 | Immutable `Map<K,V>` | `Map.ofEntries(entry(20, "..."), ...)` |
| `Map.entry(K k, V v)` | 9 | `Map.Entry<K,V>` (record-like) | `Map.Entry imm = Map.entry("biezhi", "emmmm");` |
| `Set.of()` | 9 | Empty `Set<Object>` | `Set immutableSet = Set.of();` |
| `Set.of(E... elements)` | 9 | Immutable `Set<E>` | `Set bar = Set.of("我", "可能", "是个", ...);` |

#### Important behavior notes

- **All returned collections are immutable.** Any attempt to add, remove, or clear an element will throw `UnsupportedOperationException`.
- The empty factory methods return collections of type `List<Object>`, `Map<Object,Object>`, and `Set<Object>` respectively — type inference through `var` helps here but is not required.
- `Map.entry(k, v)` returns an *immutable* entry. Calling `setValue()` on it throws `UnsupportedOperationException`. It is primarily a convenience for building entries inside `Map.ofEntries(...)`.

#### Relationship to `var`

The examples use `var` for local-variable type inference on several assignments (e.g., `var foo = List.of(...)`), demonstrating how modern type inference pairs well with factory methods to keep code concise without sacrificing clarity.

### `DiamondOperatorExample`

**Source:** [src/main/java/io/github/biezhi/java11/collections/DiamondOperatorExample.java](src/main/java/io/github/biezhi/java11/collections/DiamondOperatorExample.java)

This class demonstrates how the diamond operator — originally introduced in Java 7 for named generic types — was extended in Java 9+ to work with **anonymous inner classes**, and how wildcards interact with the diamond.

#### `MyHandler<T>`

**Source:** [DiamondOperatorExample.MyHandler](src/main/java/io/github/biezhi/java11/collections/DiamondOperatorExample.java:14)

`MyHandler<T>` is a nested `static abstract` generic class that serves as the base for all anonymous subtypes created in `main()`.

**Fields:**

| Field | Type | Purpose |
|---|---|---|
| `content` | `T` | Holds the generic payload |

**Methods:**

| Method | Signature | Description |
|---|---|---|
| Constructor | `MyHandler(T content)` | Stores `content` and prints a Chinese log message ("构造函数收到了一条内容: ...") |
| `getContent()` | `T getContent()` | Returns the stored content |
| `setContent(T content)` | `void setContent(T content)` | Replaces the stored content |
| `handle()` | `abstract void handle()` | Abstract callback — each anonymous subclass overrides this to define its own behavior |

**Design intent:** `MyHandler` models a simple content-handling pattern: you instantiate a handler with some data, and the `handle()` method defines *what to do with that data*. Because it is abstract and concrete behavior is delegated to anonymous subclasses, the class demonstrates the diamond operator in its most typical real-world usage scenario.

#### `main()` — three diamond operator patterns

The `main` method exercises three distinct ways of using the diamond operator with anonymous inner classes:

1. **Explicit type parameter:**
   ```java
   MyHandler<Integer> intHandler = new MyHandler<>(1) {
       @Override
       public void handle() {
           System.out.println("收到红包 > " + getContent() + "元");
       }
   };
   ```
   The declared type on the left is `MyHandler<Integer>`, and the diamond `<>` on the right lets the compiler infer the type argument for the anonymous subclass constructor.

2. **Wildcard type parameter (`? extends Integer`):**
   ```java
   MyHandler<? extends Integer> intHandler1 = new MyHandler<>(10) { ... };
   ```
   Demonstrates that wildcards can be used with the diamond, though the wildcard constrains what can be read from the handler (you can still call `getContent()` because `? extends Integer` guarantees a readable Integer).

3. **Unbounded wildcard (`?`):**
   ```java
   MyHandler<?> handler = new MyHandler<>("魔法师") { ... };
   ```
   The unbounded wildcard accepts any reference type. This is the most flexible declaration but restricts reads to `Object`.

#### Historical context (from the class Javadoc)

The Javadoc explains in Chinese that Java 7 introduced the diamond operator to reduce verbose code and improve readability. Java 8 had limitations with the diamond and anonymous inner classes, which Oracle fixed and shipped as part of Java 9. This example serves as a practical illustration of that improvement.

## How It Works

### Factory-method workflow (Example.java)

```mermaid
flowchart TD
    subgraph collectionAPIs["Java 9+ Collection Factory Methods"]
        direction TB
        list["List.of(...)"]
        map["Map.of(...)"]
        mapentries["Map.ofEntries(...)"]
        set["Set.of(...)"]
        mapentry["Map.entry(...)"]
    end

    list --> immutableList["Immutable List"]
    map --> immutableMap["Immutable Map"]
    mapentries --> entryMap["Map from entries"]
    set --> immutableSet["Immutable Set"]
    mapentry --> singleEntry["Single Map.Entry"]

    immutableList -.-> note1["All returned collections are<br/>immutable — throws<br/>UnsupportedOperationException<br/>on modification"]
    immutableMap -.-> note1
    immutableSet -.-> note1
```

When `Example.main()` executes, it follows a straightforward pattern for each API:

1. **Call a factory method** — e.g., `List.of("biezhi", "github", "...")`.
2. **Store the result** — either in a typed variable (`var foo`) or an explicitly declared one (`List immutableList`).
3. **Use the collection** — read-only operations work normally; mutation attempts throw `UnsupportedOperationException`.

There is no runtime transformation or caching — these are simple static factory methods that delegate to internal `ImmutableCollections` implementations (private classes in the JDK).

### Diamond-operator workflow (DiamondOperatorExample.java)

```mermaid
flowchart TD
    subgraph collections["io.github.biezhi.java11.collections"]
        direction TB
        Example["Example<br/>JDK collection factory API demos"]
        DiamondOperatorExample["DiamondOperatorExample<br/>Diamond operator + anonymous inner classes"]
        MyHandler["MyHandler&lt;T&gt;<br/>Abstract generic content handler"]
        Example -- uses --> ExampleOf["List.of, Map.of, Set.of,<br/>Map.entry"]
        DiamondOperatorExample -- contains --> MyHandler
        DiamondOperatorExample -- main demonstrates --> Anonymous["Anonymous inner classes<br/>with diamond operator"]
    end
```

The diamond operator flow in `DiamondOperatorExample.main()` works as follows:

1. **Define an abstract generic base class** (`MyHandler<T>`) with a typed payload and an abstract `handle()` callback.
2. **Instantiate an anonymous inner class** using `new MyHandler<>(value) { ... }`, where the diamond `<>` infers the type from the left-hand-side declaration.
3. **Override `handle()`** to define custom behavior for the specific instance.
4. **Call `handle()`** on the resulting reference, which dispatches to the anonymous subclass's implementation.

This pattern is common in callback-based APIs (event listeners, strategy objects, etc.). The key insight this example highlights is that prior to Java 9, you could *not* use `new Handler<>() { ... }` for anonymous subclasses — you had to repeat the type parameter on both sides. The diamond now eliminates that redundancy.

## Data Model

There are no persistent data models in this package. The two classes are purely self-contained demos. However, the following conceptual data structures emerge:

| Structure | Source | Description |
|---|---|---|
| `MyHandler<T>` | [DiamondOperatorExample.MyHandler](src/main/java/io/github/biezhi/java11/collections/DiamondOperatorExample.java:14) | Generic wrapper holding a single `T content` value and an abstract processing callback. |
| Immutable collections | [Example](src/main/java/io/github/biezhi/java11/collections/Example.java:16) | Factory-method-created `List`, `Set`, `Map`, and `Map.Entry` instances — all internally backed by JDK-private `ImmutableCollections` classes. |

## Dependencies and Integration

This module has no external dependencies beyond the JDK standard library. It uses:

- `java.util.List`, `java.util.Map`, `java.util.Set` (JDK)
- `java.util.Map.entry` (JDK 9+)
- `var` (JDK 10+) for local-variable type inference

The package is a standalone educational demo — it does not depend on or integrate with any other module in the codebase. It sits under `java11` alongside other JDK feature showcase packages (`time`, `string`, `http`, `var`, `interfaces`, `files`, `processor`, `trywithresources`).

## Notes for Developers

- **Immutable collections are read-only.** If you need a mutable collection, wrap the factory result: `new ArrayList<>(List.of(...))`, `new HashMap<>(Map.of(...))`, or `new HashSet<>(Set.of(...))`.
- **`Map.ofEntries` and `Map.entry` require explicit type parameters** (or `var`) because the factory methods cannot infer types from empty `entry(...)` calls alone.
- **The diamond operator on anonymous inner classes only works when the superclass has a type parameter.** It does not apply to non-generic classes.
- **Wildcard declarations with the diamond** (`MyHandler<? extends T>`, `MyHandler<?>`) work but have access constraints — you can only read from `? extends` declarations (as the bound type) and from `?` as `Object`.
- This is a **demonstration package**, not production code. Methods are `public static void main()` with no external visibility. Treat examples as learning material, not templates for a codebase.
