SkillAgentSearch skills...

Functional

Functional programming for Java. Enhanced switch or simple pattern matching supported; String Interpolation supported; Java Functional Interface that more simpler and easier to use; Provide an immutable and thread-safe date time class; a stopwatch utility class, etc. 提供更简单更好用的Java函数式编程接口、增强版switch、字符串插值;提供不可变且线程安全的时间类、秒表工具类等等。且兼容Java8与Java9模块化系统

Install / Use

/learn @io-fairy/Functional

README

<h1 align="center">📚Functional</h1>

English | 简体中文


Functional is a powerful Java utility library providing various functional programming tools:

  • 🔥 Provides simpler and better Java functional programming interfaces
  • 🔥 Enhanced switch statement (simple pattern matching support)
  • 🔥 String interpolation (SI)
  • 🔥 Tuple type support
  • 🕒 <u>Immutable and thread-safe</u> DateTime utility class with unified temporal API
    • 🔺 Powerful datetime API
      • Automatic parsing of multiple datetime formats
      • Time unit-based rounding operations (round, ceil, floor)
      • Temporal offset calculations
      • Temporal Interval calculations
      • Custom datetime formatting
      • Week information retrieval and formatting
      • Conversion between temporal types
    • 🔺 Supports multiple temporal types: Date, Calendar, LocalDateTime, ZonedDateTime, OffsetDateTime, Instant, LocalDate
  • 🕒 Convenient Stopwatch utility for benchmarking code execution times
  • 💡 Compatibility with Java 8+ and Java 9+ module systems
  • ...

🗺️ Overview

🚀Quick Start

🛠️Environment

  • JDK 9.0.4 (Compatibility with Java 8+ and Java 9+ module systems)
  • Apache maven 3.6.1

💿 Integration

Maven

<dependency>
  <groupId>com.iofairy</groupId>
  <artifactId>functional</artifactId>
  <version>0.6.1</version>
</dependency>

Gradle

implementation 'com.iofairy:functional:0.6.1'

📘Enhanced Switch (Pattern Matching)

Enhanced switch supports:

  • Traditional switch-compatible types (byte, short, char, int, enum, String)
  • Arbitrary type matching
  • Object type checks (replaces instanceof)
  • Conditional branching (replaces if-else)

Object Value Matching

For value equality checks (requires static import: import static com.iofairy.pattern.Pattern.*;)

  • Value-returning pattern matching
import static com.iofairy.pattern.Pattern.*;

String s = "5";
// with return value
String result = match(s)
        .when("1", v -> v + v)
        .when("2", v -> v + "a")
        .when(in("3", "4", "5", "6"), v -> v + " - abcd")    // The in() is used to match multiple values at once.
        .orElse(v -> "no match");

/*
 * it is equivalent to the code below.
 */
String switchResult;
switch (s) {
    case "1":
        switchResult = s + s;
        break;
    case "2":
        switchResult = s + "a";
        break;
    case "3":
    case "4":
    case "5":
    case "6":
        switchResult = s + " - abcd";
        break;
    default:
        switchResult = "no match";
}
  • Void-returning pattern matching
import static com.iofairy.pattern.Pattern.*;

int i = 10;
// returns null
Void nullValue = match(i)
        .when(1,
                /*
                 * if you want to match `when(V matchValue, V1<V> action)` not `when(V matchValue, R1<V, R> action)`,
                 * you need add `{ }`, see: void-compatible and value-compatible
                 */
                v -> { System.out.println("match value:" + v); })  // add {} to void-compatible. 
        .whenNext(10,
                v -> System.out.println("match value:" + v + " whenNext continue..."))
        .when(20,
                v -> System.out.println("match value:" + v))
        .orElse(
                v -> System.out.println("--orElse--"));
/*
 * output:
 * match value:10 whenNext continue...
 * --orElse--
 */

🔔️Note: Lambda expressions void-compatible or value-compatible

Null Value Handling

Can match null values, eliminating the need for verbose null checks like:if(xxx == null){...} else {...}
🔔️ Recommendation: Prioritize null matching to prevent NullPointerException - if a variable is null, subsequent branches are skipped automatically.

import static com.iofairy.pattern.Pattern.*;

String s = null;
String strResult1 = match(s)
        // Avoid "Ambiguous method call", if you want to match `null` value, you need use `(String) null` or in(null)
        .when((String) null, v -> "string null value")
        .when("abcd", v -> "is not null")
        .orElse(v -> "other value");

assertEquals("string null value", strResult1);

String strResult2 = match(s)
        .when(in(null), v -> "contains null value")
        .when("abcd", v -> "is not null")
        .orElse(v -> "other value");

assertEquals("contains null value", strResult2);

String strResult3 = match(s)
        .when(in("a", "b", null, "c"), v -> "contains null value")
        .when("abcd", v -> "is not null")
        .orElse(v -> "other value");

assertEquals("contains null value", strResult3);


Tuple2<String, Integer> t2 = null;
String classMatch = match(t2, TYPE)
        .when(Integer.class, v -> "integer class")
        .when(null, v -> "value is null: " + v)
        .when(Tuple2.class, v -> "tuple2 class")
        .orElse(v -> "other class");

assertEquals("value is null: " + null, classMatch);

String res = match(null, VALUE)
        .when(null, v -> "null value")
        .orElse(v -> "other value");
assertEquals("null value", res);

Type-based Matching

import static com.iofairy.pattern.Pattern.*;

Object o = Tuple.of("zs", 20);
// add `TYPE` to match Class<?>. 
Integer result = match(o, TYPE)  
        .when(Integer.class, v -> v + 10)
        .when(Tuple2.class,  v -> v.arity())
        .when(String.class,  v -> v.contains("abc") ? 20 : 30)
        .orElse(v -> 40);
        

/*
 * it is equivalent to the code below.
 */
Integer ifResult;
if (o instanceof Integer) {
    ifResult = (Integer) o + 10;
} else if (o instanceof Tuple2) {
    ifResult = ((Tuple2) o).arity();
} else if (o instanceof String) {
    ifResult = ((String) o).contains("abc") ? 20 : 30;
} else {
    ifResult = 40;
}

String Pattern Matching

import static com.iofairy.pattern.Pattern.*;

String str = "aBcdE123.$fGHIj";
// ignore case match
String matchRes1 = match(str, IGNORECASE)
        .when((String) null, v -> "match null")
        .when("abcd", v -> "match abcd")
        .when("abcde123.$fGHIj", v -> "ignore case match")
        .orElse(v -> "no match");
assertEquals("ignore case match", matchRes1);
// CONTAIN match
String matchRes2 = match(str, CONTAIN)
        .when("abcd", v -> "abcd")
        .when("E123", v -> "E123")
        .orElse(v -> "no match");
assertEquals("E123", matchRes2);
// ignore case for contain
String matchRes3 = match(str, ICCONTAIN)
        .when("abcd1", v -> "abcd1")
        .when(in(null, "aaa", ".$fghi", "123"), v -> ".$fghi")
        .orElse(v -> "no match");
assertEquals(".$fghi", matchRes3);
// PREFIX
String matchRes4 = match(str, PREFIX)
        .when("abcd", v -> "abcd")
        .when("aBcd", v -> "aBcd")
        .orElse(v -> "no match");
assertEquals("aBcd", matchRes4);
// ignore case for suffix
String matchRes5 = match(str, ICSUFFIX)
        .when("fghij", v -> "fGHIj")
        .when("aBcd", v -> "aBcd")
        .orElse(v -> "no match");
assertEquals("fGHIj", matchRes5);

Conditional Matching (alternative to if-else)

import static com.iofairy.pattern.Pattern.*;

int i = 10;
String result = match()
        .when(i == 0,
                v -> "i is zero")
        .when(i < 5 && i > 0,
                v -> "i is between 0~5")
        .when(i > 5,
                v -> "i is greater than 5")
        .orElse(v -> "i is equals to: " + v);
        
System.out.println("match result:" + result);


/*
 * it is equivalent to the code below
 */
String ifResult;
if (i == 0) {
    ifResult = "i is zero";
} else if (i < 5 && i > 0) {
    ifResult = "i is between 0~5";
} else if (i > 5) {
    ifResult = "i is greater than 5";
} else {
    ifResult = "i is equals to: " + i;
}

🔥String Interpolator

What can do?

Replaces cumbersome + concatenation and Java's built-in interpolators (MessageFormat.format() or String.format())

  • Built-in Java
int id = 12345;
String name = "zhangsan";
float height = 180.5f; 

// use `+` concatenation
String res1 = "id: " + id + "  名字:" + name + "  身高(cm): " + height;
System.out.println(res1);

// use MessageFormat.format
String res2 = MessageFormat.format("id: {0}  名字:{1}  身高(cm): {2}", id, name, height);
System.out.println(res2);

// use String.format
String res3 = String.format("id: %d  名字:%s  身高(cm): %.1f", id, name, height);
System.out.println(res3);
  • **use string in
View on GitHub
GitHub Stars11
CategoryCustomer
Updated2mo ago
Forks6

Languages

Java

Security Score

95/100

Audited on Jan 15, 2026

No findings