This article is participating in the Java Theme Month – Java Debug Notes EventActive link

Recently in Excel import, data verification is indispensable, but different data fields have different verification policies, multifous, even uncertain, so I made a verification policy tool, the verification policy abstract out. Here try an assertion function provided by the Java 8 interface Java. Util. The function. The Predicate < T >, very to force! The validation policy is elegantly encapsulated, and today I will briefly share my experience with this functional interface.

Of course, later I thought of a way to use the JSR303 check in the import check, this method was eliminated by me, this is a story later.

The application of the Predicate

Take a look at the results first:

    boolean validated = new Validator<String>()
            .with(s -> s.length() > 5)
            .with(s -> s.startsWith("felord"))
            .with(s -> s.endsWith("cn"))
            .with(s -> s.contains("."))
            .validate("felord.cn");
Copy the code

I’ll take the example of verifying the String felord.cn with a series of Predicate

assertions. This is not limited to the methods provided by String, as long as you satisfy String -> Boolean, which means that a String entry can return a Boolean value. For example, if we are retrieving a string from a database, we can write a very common UserService to check whether the username exists or is valid:

public class UserServiceImpl implements UserService {
    @Override
    public boolean checkUserByName(String name) {
        return false; }}Copy the code

The corresponding verification can be changed to:

    UserServiceImpl userService = new UserServiceImpl();
    boolean validated = new Validator<String>()
             // Whether the length is greater than 5
            .with(s -> s.length() > 5)
             // Whether to start with felord
            .with(s -> s.startsWith("felord"))
             // Database validation
            .with(userService::checkUserByName)
             // Check the target
            .validate("felord.cn");
Copy the code







import java.util.function.Predicate;
 
public class Validator<T> {
    /** * is initialized to true true && Other booleans are used to determine the value */
    private Predicate<T> predicate = t -> true;

    /** * Add a checksum policy for unlimited refilling 😀 **@param predicate the predicate
     * @return the validator
     */
    public Validator<T> with(Predicate<T> predicate) {
        this.predicate = this.predicate.and(predicate);
        return this;
    }

    /** * Perform verification **@param t the t
     * @return the boolean
     */
    public boolean validate(T t) {
        returnpredicate.test(t); }}Copy the code

The logic is not very complex, but it can handle complex combinations of assertion strategies. Let’s take a look at Predicate

.

Predicate

@FunctionalInterface
public interface Predicate<T> {

    /** * function interface method */
    boolean test(T t);

    /** * and the default method is equivalent to the logical operator && */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    /** * negate the default method is equivalent to the logical operator! * /
    default Predicate<T> negate(a) {
        return(t) -> ! test(t); }/ * * * or the default method is equal to the logical operators | | * /
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    /** * this method is provided to {@linkObjects#equals(Object, Object)}, not open to developers */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null== targetRef) ? Objects::isNull : object -> targetRef.equals(object); }}Copy the code

The assertion function interface provides the test method for us to develop and implement, and provides and negate, or corresponding to Java logic operators &&,! , | |. Boolean variable operation is fully satisfied, which is very useful when multiple conditional strategy combination is needed.

conclusion

Today answers a question from a student about how lambda expressions and functional programming work by demonstrating the use of Predicate

. The birth of functional programming in Java “killed” many design patterns, especially the policy pattern. If you want to use functional programming well, you need to strengthen the abstraction ability, do not force the function. Well, today’s share here, a lot of attention, like, forward, is the biggest support for me.