All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.iofairy.pattern.Pattern Maven / Gradle / Ivy

Go to download

Functional Programming for Java 8+ and compatible with the modular system of Java 9+.

There is a newer version: 0.5.10
Show newest version
/*
 * Copyright (C) 2021 iofairy, 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.iofairy.pattern;

import com.iofairy.base.None;
import com.iofairy.lambda.R1;
import com.iofairy.pattern.mapping.*;
import com.iofairy.pattern.type.*;

import java.util.Objects;

/**
 * Pattern Matching for Java
 *
 * @since 0.0.1
 */
public class Pattern {
    public static final PatternDefault DEFAULT = PatternDefault.DEFAULT;      // DEFAULT can match by value or boolean
    public static final PatternValue VALUE = PatternValue.VALUE;              // match by value
    public static final PatternType TYPE = PatternType.TYPE;                  // match by value type(Class)
    public static final PatternString STRING = PatternString.STRING;          // match by String value
    public static final PatternString IGNORECASE = PatternString.IGNORECASE;  // match by String value ignore case
    public static final PatternString CONTAIN = PatternString.CONTAIN;        // match by String value using String.contains
    public static final PatternString PREFIX = PatternString.PREFIX;          // match by String value using String.startsWith
    public static final PatternString SUFFIX = PatternString.SUFFIX;          // match by String value using String.endsWith
    public static final PatternString ICCONTAIN = PatternString.ICCONTAIN;    // ignore case for contain
    public static final PatternString ICPREFIX = PatternString.ICPREFIX;      // ignore case for prefix
    public static final PatternString ICSUFFIX = PatternString.ICSUFFIX;      // ignore case for suffix

    public static None NONE = None.NONE;
    /*
     * Value for null pattern
     */
    public static final PatternNull1 VALUE1 = PatternNull1.VALUE1;
    public static final PatternNull2 VALUE2 = PatternNull2.VALUE2;
    public static final PatternNull3 VALUE3 = PatternNull3.VALUE3;
    public static final PatternNull4 VALUE4 = PatternNull4.VALUE4;
    public static final PatternNull5 VALUE5 = PatternNull5.VALUE5;
    public static final PatternNull6 VALUE6 = PatternNull6.VALUE6;
    public static final PatternNull7 VALUE7 = PatternNull7.VALUE7;
    public static final PatternNull8 VALUE8 = PatternNull8.VALUE8;


    /**
     * {@code match} can instead of {@code switch} statement or {@code if} statement. 
* 使用 match 来替代 switch 和 if 语句
* Examples: *
{@code
     * String s = "5";
     * String result = match(s)
     *         .when("1", v -> v + v)
     *         .when("2", v -> v + "a")
     *         .when(in("3", "4", "5", "6"), v -> v + " - abcd")
     *         .orElse(v -> "no match");
     *
     * System.out.println("match result: " + result);
     * }
* * @param value value * @param value type * @return MixMatcherMapping * @since 0.0.1 */ public static ValueMatcherMapping match(V value) { return match(value, DEFAULT); } public static ValueMatcherMapping match(V value, PatternDefault patternDefault) { Objects.requireNonNull(patternDefault); return new ValueMatcherMapping(value); } public static ValueMatcherMapping match(V value, PatternValue patternValue) { Objects.requireNonNull(patternValue); return new ValueMatcherMapping(value); } /** * There is multiple {@code if} statements, but they're not related, * use {@code match()} without value.
* 当你有多条if语句,但是彼此并不相关时,可以使用不带value的match。
* Examples: *
{@code
     * int i = 10;
     * String s = "abc";
     * Object o = new Object();
     *
     * String res = match()
     *              .when(i == 5,           v -> "i == 5")
     *              .when(s.equals("abc"),  v -> "abc")
     *              .when(o == null,        v -> "object is null")
     *              .orElse(v -> null);
     * }
* * @return BooleanMatcherMapping * @see #match(None) * @since 0.0.1 */ public static BooleanMatcherMapping match() { return match(NONE); } public static BooleanMatcherMapping match(None value) { return new BooleanMatcherMapping<>(value); } /** * Use Type Matcher instead of {@code instanceof}.
* 此 {@code match()} 函数可替代 {@code instanceof} 类型检测与类型转换功能。
* Examples: *
{@code
     * Object o = Tuple.of("zs", 20);
     *
     * 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: *
{@code
     * 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;
     * }
     * }
* * @param value value * @param patternType {@link PatternType} * @param value type * @return TypeMatcherMapping * @since 0.0.1 */ public static TypeMatcherMapping match(V value, PatternType patternType) { Objects.requireNonNull(patternType); return new TypeMatcherMapping<>(value); } /** * Pattern matching for String.
* 为字符串提供强大的模式匹配。
* Examples: *
{@code
     * String str = "aBcdE123.$fGHIj";
     *
     * // ignore case match
     * String res1 = match(str, IGNORECASE)
     *         .when((String) null,     v -> "match null")
     *         .when("abcd",            v -> "match abcd")
     *         .when("abcde123.$fGHIj", v -> "ignore case match")        // match this
     *         .orElse(v -> "no match");
     *
     * // CONTAIN match
     * String res2 = match(str, CONTAIN)
     *         .when("abcd", v -> "abcd")
     *         .when("E123", v -> "E123")        // match this
     *         .orElse(v -> "no match");
     *
     * // ignore case for contain
     * String res3 = match(str, ICCONTAIN)
     *         .when("abcd1",   v -> "abcd1")
     *         .when(in(null, "aaa", ".$fghi", "123"), v -> ".$fghi")    // match this
     *         .orElse(v -> "no match");
     *
     * // PREFIX
     * String res4 = match(str, PREFIX)
     *         .when("abcd",    v -> "abcd")
     *         .when("aBcd",    v -> "aBcd")         // match this
     *         .orElse(v -> "no match");
     *
     * // ignore case for suffix
     * String res5 = match(str, ICSUFFIX)
     *         .when("fghij",   v -> "fGHIj")        // match this
     *         .when("aBcd",    v -> "aBcd")
     *         .orElse(v -> "no match");
     * }
* * @param value value * @param patternString {@link PatternString} * @return StringMatcherMapping * @since 0.0.1 */ public static StringMatcherMapping match(String value, PatternString patternString) { Objects.requireNonNull(patternString); return new StringMatcherMapping(value, patternString); } public static ClassValueMatcherMapping> match(Class clazz) { return new ClassValueMatcherMapping<>(clazz); } /** * The values in {@code .when(value)} are preprocessed by {@code preAction} and then {@code match}.
* 对 when 中的值进行预处理以后再进行模式匹配
* Examples: *
{@code
     * String str = "123abc";
     *
     * R1 preAction = s -> "123" + (s == null ? null : s.toLowerCase());
     * String res1 = match(str, preAction, String.class)
     *         .when("123", v -> "1 " + v + "-- 123")
     *         .when("123ABC", v -> "2 " + v + "-- 123ABC")
     *         .when("ABC", v -> "4 " + v + "-- ABC")           // will be matched
     *         .orElse(v -> "orElse " + v);
     * System.out.println(res1);   // output: 4 123abc-- ABC
     * }
* * @param value value * @param preAction Preprocess for value in {@code .when(value)} * @param value type * @return ActionValueMatcherMapping * @since 0.0.1 */ public static ActionValueMatcherMapping match(V value, R1 preAction) { Objects.requireNonNull(preAction); return new ActionValueMatcherMapping<>(value, preAction); } public static ActionValueMatcherMapping match(V value, R1 preAction, Class clazz) { Objects.requireNonNull(preAction); return new ActionValueMatcherMapping<>(value, preAction); } public static ActionNoneMatcherMapping match(R1 preAction, Class clazz) { Objects.requireNonNull(preAction); return new ActionNoneMatcherMapping<>(NONE, preAction); } /** * 适用于判断多个值是否为null值(或其他终止条件),只要其中一个值满足终止条件,则立即 {@code return} 方法,终止后续语句运算。

* Examples:

*
{@code
     * public String patternCheckNull() {
     *     Account account = new Account("12345", "", "aaaabbbb");
     *     Order order = new Order("order_123456", 10.5, new User("zs", 10, account));
     *
     *     Tuple7 values = matchNull()
     *             .whenV(order,   v -> v.buyer,     "order is null or order.buyer is null!")
     *             .whenW(VALUE1,  v -> v.account,   v -> "user " + v._1.name + "'s account is null!")
     *             .whenV(order,   v -> v.orderId,   G::isBlank, "order.orderId is blank!")
     *             .whenV(order,   v -> v.price,     v -> v < 0, "order.price < 0!")
     *             .whenW(VALUE2,  v -> v.userName,  G::isEmpty, "order.buyer.account.userName is empty!")
     *             .whenW(VALUE1,  v -> v.age,       v -> v < 0, "order.buyer.age < 0!")
     *             .orElse(null);
     *
     *     User user = values._1;
     *     Account account1 = values._2;
     *     String orderId = values._3;
     *     Double price = values._4;
     *     String userName = values._5;
     *     Integer age = values._6;
     *     String msg = values._7;
     *
     *     return msg;
     * }
     * 
* It is equivalent to the code below:

*
     * public String commonCheckNull() {
     *     Account account = new Account("12345", "", "aaaabbbb");
     *     Order order = new Order("order_123456", 10.5, new User("zs", 10, account));
     *
     *     String msg = null;
     *     if (order == null || order.buyer == null) {
     *         return "order is null or order.buyer is null!";
     *     }
     *     User user = order.buyer;
     *     if (user.account == null) {
     *         return "user " + user.name + "'s account is null!";
     *     }
     *     if (G.isBlank(order.orderId)) {
     *         return "order.orderId is blank!";
     *     }
     *     if (order.price < 0) {
     *         return "order.price < 0!";
     *     }
     *     if (G.isEmpty(user.account.userName)) {
     *         return "order.buyer.account.userName is empty!";
     *     }
     *     if (user.age < 0) {
     *         return "order.buyer.age < 0!";
     *     }
     *
     *     return null;
     * }
     * }
* * @return NullMatcherMapping */ public static NullMatcherMapping matchNull() { return new NullMatcherMapping<>(None.NONE); } /*################################################################################### ************************************************************************************ ------------------------------------------------------------------------------------ ********************* Referencing methods of other classes ********************* ********************* 引用其他类中的方法,方便静态导入 ********************* ------------------------------------------------------------------------------------ ************************************************************************************ ###################################################################################*/ @SafeVarargs public static PatternIn in(T... values) { return PatternIn.in(values); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy