# Predicater

## Purpose

`Predicater` is a generic functional interface that defines a single-argument predicate — a boolean-valued function that tests whether an input element satisfies a certain condition. It exists inside the `Items` utility class to enable LINQ-style collection filtering (`select`, `exist`, `find`) without requiring an external library. It is the backbone of a fluent, lambda-free filtering pattern used throughout the JKKWribSvcKeiOperateCC codebase.

## Design

`Predicater<I>` follows the **Strategy pattern**. It encapsulates a boolean evaluation rule behind a single-method interface, allowing callers to pass arbitrary filter logic as first-class objects. The interface is declared as a nested interface inside `Items` (line 16608–16611 of `JKKWribSvcKeiOperateCC.java`), keeping it co-located with the utility methods (`select`, `exist`, `find`) that consume it.

Key characteristics:
- **Generic** — parameterized on type `<I>`, so it works with any element type (e.g., `HashMap<String, String>`, `CAANMsg`).
- **Stateless or stateful** — a predicate can be a pure function of its input, or it can carry configuration (keys, values, lookup tables) set at construction time.
- **No language version constraints** — because it is an explicit interface rather than a `@FunctionalInterface`, it is compatible with older Java versions that lack lambda support, enabling callers to use anonymous inner classes or named implementation classes.

## Key Methods

### `boolean evaluate(I input)`

```java
boolean evaluate(I input);
```

Evaluates the predicate against the given input and returns `true` if the input satisfies the condition, `false` otherwise.

- **Parameters**: `input` — the element to test. Its concrete type depends on the implementing class.
- **Return value**: `true` if the predicate's condition is met; `false` otherwise.
- **Side effects**: None defined by the interface contract. However, concrete implementations may carry state (see `CAANMsgFinder` for an example that makes remote service lookups inside `evaluate`).

#### Concrete Implementations

Five named classes in the codebase implement `Predicater`, each serving a distinct filtering purpose:

| Class | Type Parameter | Filtering Logic |
|-------|---------------|-----------------|
| `TextFilter` | `HashMap<String, String>` | Returns `true` if the value at a given `key` in the map equals an expected `String` value. |
| `ObjectFilter` | `HashMap<String, Object>` | Same as `TextFilter`, but the value is typed as `Object`. |
| `ListMultiFilter` | `HashMap<String, String>` | Returns `true` if the value at a given `key` matches **any** value in an `Object[]` whitelist. The Japanese comment above the class reads "マップ判定クラス" (Map Judgment Class). |
| `CAANMsgFinder` | `CAANMsg` | Returns `true` if a `CAANMsg`'s `dchs_cd` resolves to valid (non-empty, non-blacklisted) distribution channel codes via `operateCc.resolveDchsHeiyo`. It performs a remote service call inside `evaluate`. |
| `SvcKeiFinderWithTrgtSvc` / `SvcKeiFinderWithDchskmTrgtSvc` | (service-type specific) | Service-category finder predicates (names suggest business logic: "service category finder with target service"). |

## Relationships

### Who Uses Predicater

`Predicater` is consumed by three static utility methods inside `Items`:

| Method | Signature | Behavior |
|--------|-----------|----------|
| `select` | `<I> ArrayList<I> select(ArrayList<I> in, Predicater<I> p)` | Filters the list, returning only elements where `p.evaluate(item)` is `true`. |
| `exist` | `<I> boolean exist(ArrayList<I> in, Predicater<I> p)` | Short-circuit check — returns `true` on the first element that satisfies the predicate; otherwise `false`. |
| `find` | `<I> I find(ArrayList<I> in, Predicater<I> p)` | Returns the first element matching the predicate, or `null` if none match. |

These three methods form a small, self-contained DSL (Domain Specific Language) for in-memory collection queries, inspired by Java 8 Streams / LINQ but implemented using pre-Java-8 anonymous inner classes.

### Implementations

```mermaid
flowchart LR
    subgraph Items["Items"]
        direction TB
        Predicater["Predicater interface
<P> evaluate(P input)
boolean"]
        select["select(ArrayList, Predicater)
ArrayList<P>"]
        exist["exist(ArrayList, Predicater)
boolean"]
        find["find(ArrayList, Predicater)
P"]
    end

    Predicater -->|"implements"| TextFilter["TextFilter"]
    Predicater -->|"implements"| ObjectFilter["ObjectFilter"]
    Predicater -->|"implements"| ListMultiFilter["ListMultiFilter"]
    Predicater -->|"implements"| CAANMsgFinder["CAANMsgFinder"]
    Predicater -->|"implements"| SvcKeiFinder["SvcKeiFinderWithTrgtSvc / SvcKeiFinderWithDchskmTrgtSvc"]

    select -->|"consumes"| Predicater
    exist -->|"consumes"| Predicater
    find -->|"consumes"| Predicater
```

## Usage Example

The typical calling pattern creates a predicate and passes it to a `Items` utility method:

```java
// Create a predicate: find items where the "status" key equals "active"
Predicater<HashMap<String, String>> filter =
    new TextFilter("status", "active");

// Filter a list — returns only matching items
ArrayList<HashMap<String, String>> activeItems =
    Items.select(allItems, filter);

// Check existence — returns true if at least one matches
boolean hasActive = Items.exist(allItems, filter);

// Find first match — returns the first matching item or null
HashMap<String, String> firstActive = Items.find(allItems, filter);
```

For multi-value matching (the `ListMultiFilter` case):

```java
// Find items where "category" is one of {"A", "B", "C"}
Object[] allowedCategories = new Object[] { "A", "B", "C" };
Predicater<HashMap<String, String>> multiFilter =
    new ListMultiFilter("category", allowedCategories);

ArrayList<HashMap<String, String>> filtered = Items.select(items, multiFilter);
```

## Notes for Developers

- **Thread safety**: `Predicater` implementations are not thread-safe by default. `TextFilter`, `ObjectFilter`, and `ListMultiFilter` hold immutable fields after construction and are therefore safe to share. `CAANMsgFinder` holds a reference to `operateCc` and performs remote calls inside `evaluate` — concurrent use requires external synchronization.

- **Null safety**: `TextFilter.evaluate` calls `this.value.equals(itemValue)` — if `itemValue` is `null`, no `NullPointerException` occurs because `this.value` is the receiver. However, if `this.value` itself is `null`, it will throw. Callers should ensure predicates are constructed with non-null configuration values.

- **Performance**: `select`, `exist`, and `find` all iterate the list from the beginning with O(n) complexity. `exist` and `find` short-circuit on the first match. `select` must scan the entire list.

- **Nested design**: Because `Predicater` is nested inside `Items`, it is scoped as package-private (or at least inner-class scoped). Consumers access it via `Items.Predicater<I>`. This co-location reinforces the relationship between the interface and its consumers — the utility methods are the *raison d'être* of the predicate pattern here.

- **Java 8+ replacement**: In a modern Java codebase, `Predicater` would be replaced by `java.util.function.Predicate<T>` and the `Items` methods would delegate to `Stream.filter()`. The current design predates Java 8 lambdas and uses explicit anonymous inner classes for compatibility.

- **The 28 inbound connections**: The high inbound connection count reflects that `Predicater` is used ubiquitously across filtering operations throughout the JKKWribSvcKeiOperateCC system. Almost every service-category finder uses it as its core matching mechanism.
