Guava Predicate&Predicates源碼分析

Predicate

斷言,判斷一個對象是否滿足一定條件。

package com.google.common.base;

@FunctionalInterface
@GwtCompatible
public interface Predicate<T> extends java.util.function.Predicate<T> {

    @CanIgnoreReturnValue
    boolean apply(@Nullable T input);

    @Override
    boolean equals(@Nullable Object object);

	// apply的測試方法
    @Override
    default boolean test(@Nullable T input) {
    	return apply(input);
    }
}

Predicates類,Predicate接口的指南類,實現了Predicate接口並且添加了一些常用的靜態方法,主要關注apply方法。

package com.google.common.base;

@GwtCompatible(emulated = true)
public final class Predicates {
    private Predicates() {}

    // TODO(kevinb): considering having these implement a VisitablePredicate
    // interface which specifies an accept(PredicateVisitor) method.

    /**
    * 返回結果爲true的Predicate,ObjectPredicate是一個內部枚舉類
    */
    @GwtCompatible(serializable = true)
    public static <T> Predicate<T> alwaysTrue() {
    	return ObjectPredicate.ALWAYS_TRUE.withNarrowedType();
    }

    /**
    * 返回結果爲false的Predicate
    */
    @GwtCompatible(serializable = true)
    public static <T> Predicate<T> alwaysFalse() {
    	return ObjectPredicate.ALWAYS_FALSE.withNarrowedType();
    }

    /**
    * 返回判斷對象是否爲null的Predicate
    */
    @GwtCompatible(serializable = true)
    public static <T> Predicate<T> isNull() {
    	return ObjectPredicate.IS_NULL.withNarrowedType();
    }

    /**
    * 返回判斷對象是否不爲null的Predicate
    */
    @GwtCompatible(serializable = true)
    public static <T> Predicate<T> notNull() {
    	return ObjectPredicate.NOT_NULL.withNarrowedType();
    }

  /**
   * 返回與傳入predicate結果相反的predicate,NotPredicate爲內部Predicate實現類
   */
  public static <T> Predicate<T> not(Predicate<T> predicate) {
    return new NotPredicate<T>(predicate);
  }

    /**
     * 返回傳入的predicate list集合所有結果與操作之後的predicate,AndPredicate爲內部Predicate實現類
     */
    public static <T> Predicate<T> and(Iterable<? extends Predicate<? super T>> components) {
    	return new AndPredicate<T>(defensiveCopy(components));
    }

    /**
     * and重載方法,參數爲predicate可變參數
     */
    @SafeVarargs
    public static <T> Predicate<T> and(Predicate<? super T>... components) {
    	// 將多個predicate整理成一個列表,defensiveCopy爲淺拷貝
    	return new AndPredicate<T>(defensiveCopy(components));
    }

    /**
     * 將兩個predicate合併爲一個
     */
    public static <T> Predicate<T> and(Predicate<? super T> first, Predicate<? super T> second) {
    	return new AndPredicate<T>(
    		Predicates.<T>asList(checkNotNull(first), checkNotNull(second)));
    }

    /**
     * 多個predicate結果並集,OrPredicate爲內部Predicate實現類
     */
    public static <T> Predicate<T> or(Iterable<? extends Predicate<? super T>> components) {
    	// 淺拷貝多個predicate爲一個list
    	return new OrPredicate<T>(defensiveCopy(components));
    }

    /**
     * 可變參數predicate求並集
     */
    @SafeVarargs
    public static <T> Predicate<T> or(Predicate<? super T>... components) {
         return new OrPredicate<T>(defensiveCopy(components));
    }

    /**
     * 兩個predicate求並集
     */
     public static <T> Predicate<T> or(Predicate<? super T> first, Predicate<? super T> second) {
     	return new OrPredicate<T>(
     		Predicates.<T>asList(checkNotNull(first), checkNotNull(second)));
     }

    /**
     * 返回一個判斷是否相等的Prediacate
     */
     public static <T> Predicate<T> equalTo(@Nullable T target) {
     	return (target == null) ? Predicates.<T>isNull() 
     			: new IsEqualToPredicate<T>(target);
     }

    /**
     * Object.isInstance方法,以Predicate封裝返回
     */
     @GwtIncompatible // Class.isInstance
     public static Predicate<Object> instanceOf(Class<?> clazz) {
     	return new InstanceOfPredicate(clazz);
     }

    /**
     * clazz.isAssignableFrom
     */
     @GwtIncompatible // Class.isAssignableFrom
     @Beta
     @Deprecated
     public static Predicate<Class<?>> assignableFrom(Class<?> clazz) {
     	return subtypeOf(clazz);
     }

    /**
     * clazz.isAssignableFrom
     */
     @GwtIncompatible // Class.isAssignableFrom
     @Beta
     public static Predicate<Class<?>> subtypeOf(Class<?> clazz) {
     	return new SubtypeOfPredicate(clazz);
     }

    /**
     * 返回一個判斷某個元素是否在target集合內的Predicate
     */
     public static <T> Predicate<T> in(Collection<? extends T> target) {
     	return new InPredicate<T>(target);
     }

    /**
     * 類型轉換
     */
     public static <A, B> Predicate<A> compose(
     		Predicate<B> predicate, Function<A, ? extends B> function) {
     	return new CompositionPredicate<A, B>(predicate, function);
     }

    /**
     * 使用正則表達式進行字符串匹配
     */
    @GwtIncompatible // Only used by other GWT-incompatible code.
    public static Predicate<CharSequence> containsPattern(String pattern) {
    	return new ContainsPatternFromStringPredicate(pattern);
    }

    /**
     * 使用JDK正則表達式進行字符串匹配
     */
    @GwtIncompatible(value = "java.util.regex.Pattern")
    public static Predicate<CharSequence> contains(Pattern pattern) {
    	return new ContainsPatternPredicate(new JdkPattern(pattern));
    }

    // End public API, begin private implementation classes.

    // Package private for GWT serialization.
    enum ObjectPredicate implements Predicate<Object> {
    	/** @see Predicates#alwaysTrue() */
    	ALWAYS_TRUE {
            @Override
            public boolean apply(@Nullable Object o) {
            	return true;
        	}

            @Override
            public String toString() {
            	return "Predicates.alwaysTrue()";
            }
    	},
        /** @see Predicates#alwaysFalse() */
        ALWAYS_FALSE {
            @Override
            public boolean apply(@Nullable Object o) {
            	return false;
            }

            @Override
            public String toString() {
            	return "Predicates.alwaysFalse()";
            }
        },
        /** @see Predicates#isNull() */
        IS_NULL {
            @Override
            public boolean apply(@Nullable Object o) {
            	return o == null;
            }

            @Override
            public String toString() {
	            return "Predicates.isNull()";
            }
        },
        /** @see Predicates#notNull() */
        NOT_NULL {
            @Override
            public boolean apply(@Nullable Object o) {
            	return o != null;
            }

            @Override
            public String toString() {
            	return "Predicates.notNull()";
            }
        };

        @SuppressWarnings("unchecked") // safe contravariant cast
        <T> Predicate<T> withNarrowedType() {
        	return (Predicate<T>) this;
        }
	}

    /** @see Predicates#not(Predicate) */
    private static class NotPredicate<T> implements Predicate<T>, Serializable {
        final Predicate<T> predicate;

        NotPredicate(Predicate<T> predicate) {
        	this.predicate = checkNotNull(predicate);
        }

        @Override
        public boolean apply(@Nullable T t) {
        	return !predicate.apply(t);
        }

        @Override
        public int hashCode() {
        	return ~predicate.hashCode();
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj instanceof NotPredicate) {
                NotPredicate<?> that = (NotPredicate<?>) obj;
                return predicate.equals(that.predicate);
            }
            return false;
        }

        @Override
        public String toString() {
        	return "Predicates.not(" + predicate + ")";
        }

        private static final long serialVersionUID = 0;
    }

    /** @see Predicates#and(Iterable) */
    private static class AndPredicate<T> implements Predicate<T>, Serializable {
        private final List<? extends Predicate<? super T>> components;

        private AndPredicate(List<? extends Predicate<? super T>> components) {
        	this.components = components;
        }

        @Override
        public boolean apply(@Nullable T t) {
            // Avoid using the Iterator to avoid generating garbage (issue 820).
            for (int i = 0; i < components.size(); i++) {
                if (!components.get(i).apply(t)) {
                	return false;
                }
            }
            return true;
        }

        @Override
        public int hashCode() {
            // add a random number to avoid collisions with OrPredicate
            return components.hashCode() + 0x12472c2c;
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj instanceof AndPredicate) {
                AndPredicate<?> that = (AndPredicate<?>) obj;
                return components.equals(that.components);
            }
            return false;
        }

        @Override
        public String toString() {
        	return toStringHelper("and", components);
        }

        private static final long serialVersionUID = 0;
    }

    /** @see Predicates#or(Iterable) */
    private static class OrPredicate<T> implements Predicate<T>, Serializable {
        private final List<? extends Predicate<? super T>> components;

        private OrPredicate(List<? extends Predicate<? super T>> components) {
        	this.components = components;
        }

        @Override
        public boolean apply(@Nullable T t) {
            // Avoid using the Iterator to avoid generating garbage (issue 820).
            for (int i = 0; i < components.size(); i++) {
                if (components.get(i).apply(t)) {
                	return true;
                }
            }
            return false;
        }

        @Override
        public int hashCode() {
            // add a random number to avoid collisions with AndPredicate
            return components.hashCode() + 0x053c91cf;
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj instanceof OrPredicate) {
                OrPredicate<?> that = (OrPredicate<?>) obj;
                return components.equals(that.components);
            }
            return false;
        }

        @Override
        public String toString() {
        	return toStringHelper("or", components);
        }

        private static final long serialVersionUID = 0;
    }

    private static String toStringHelper(String methodName, Iterable<?> components) {
        StringBuilder builder = 
        	new StringBuilder("Predicates.").append(methodName).append('(');
        boolean first = true;
        for (Object o : components) {
            if (!first) {
            	builder.append(',');
            }
            builder.append(o);
            first = false;
        }
        return builder.append(')').toString();
    }

    /** @see Predicates#equalTo(Object) */
    private static class IsEqualToPredicate<T> implements Predicate<T>, Serializable {
        private final T target;

        private IsEqualToPredicate(T target) {
        	this.target = target;
        }

        @Override
        public boolean apply(T t) {
        	return target.equals(t);
        }

        @Override
        public int hashCode() {
        	return target.hashCode();
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj instanceof IsEqualToPredicate) {
                IsEqualToPredicate<?> that = (IsEqualToPredicate<?>) obj;
                return target.equals(that.target);
            }
            return false;
        }

        @Override
        public String toString() {
        	return "Predicates.equalTo(" + target + ")";
        }

        private static final long serialVersionUID = 0;
    }

    /** @see Predicates#instanceOf(Class) */
    @GwtIncompatible // Class.isInstance
    private static class InstanceOfPredicate implements Predicate<Object>, Serializable {
        private final Class<?> clazz;

        private InstanceOfPredicate(Class<?> clazz) {
            this.clazz = checkNotNull(clazz);
        }

        @Override
        public boolean apply(@Nullable Object o) {
            return clazz.isInstance(o);
        }

        @Override
        public int hashCode() {
            return clazz.hashCode();
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj instanceof InstanceOfPredicate) {
                InstanceOfPredicate that = (InstanceOfPredicate) obj;
                return clazz == that.clazz;
            }
            return false;
        }

        @Override
        public String toString() {
            return "Predicates.instanceOf(" + clazz.getName() + ")";
        }

        private static final long serialVersionUID = 0;
    }

    /** @see Predicates#subtypeOf(Class) */
    @GwtIncompatible // Class.isAssignableFrom
    private static class SubtypeOfPredicate implements Predicate<Class<?>>, Serializable {
        private final Class<?> clazz;

        private SubtypeOfPredicate(Class<?> clazz) {
        	this.clazz = checkNotNull(clazz);
        }

        @Override
        public boolean apply(Class<?> input) {
        	return clazz.isAssignableFrom(input);
        }

        @Override
        public int hashCode() {
        	return clazz.hashCode();
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj instanceof SubtypeOfPredicate) {
                SubtypeOfPredicate that = (SubtypeOfPredicate) obj;
                return clazz == that.clazz;
            }
            return false;
        }

        @Override
        public String toString() {
        	return "Predicates.subtypeOf(" + clazz.getName() + ")";
        }

        private static final long serialVersionUID = 0;
    }

    /** @see Predicates#in(Collection) */
    private static class InPredicate<T> implements Predicate<T>, Serializable {
        private final Collection<?> target;

        private InPredicate(Collection<?> target) {
        	this.target = checkNotNull(target);
        }

        @Override
        public boolean apply(@Nullable T t) {
            try {
            	return target.contains(t);
            } catch (NullPointerException e) {
            	return false;
            } catch (ClassCastException e) {
            	return false;
            }
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj instanceof InPredicate) {
                InPredicate<?> that = (InPredicate<?>) obj;
                return target.equals(that.target);
            }
            return false;
        }

        @Override
        public int hashCode() {
       		return target.hashCode();
        }

        @Override
        public String toString() {
        	return "Predicates.in(" + target + ")";
        }

        private static final long serialVersionUID = 0;
    }

    /** @see Predicates#compose(Predicate, Function) */
    private static class CompositionPredicate<A, B> implements Predicate<A>, Serializable {
        final Predicate<B> p;
        final Function<A, ? extends B> f;

        private CompositionPredicate(Predicate<B> p, Function<A, ? extends B> f) {
            this.p = checkNotNull(p);
            this.f = checkNotNull(f);
        }

        @Override
        public boolean apply(@Nullable A a) {
        	return p.apply(f.apply(a));
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj instanceof CompositionPredicate) {
                CompositionPredicate<?, ?> that = (CompositionPredicate<?, ?>) obj;
                return f.equals(that.f) && p.equals(that.p);
            }
            return false;
        }

        @Override
        public int hashCode() {
        	return f.hashCode() ^ p.hashCode();
        }

        @Override
        public String toString() {
            // TODO(cpovirk): maybe make this look like the method call does ("Predicates.compose(...)")
            return p + "(" + f + ")";
        }

        private static final long serialVersionUID = 0;
    }

    /** @see Predicates#contains(Pattern) */
    @GwtIncompatible // Only used by other GWT-incompatible code.
    private static class ContainsPatternPredicate implements Predicate<CharSequence>, Serializable {
        final CommonPattern pattern;

        ContainsPatternPredicate(CommonPattern pattern) {
        	this.pattern = checkNotNull(pattern);
        }

        @Override
        public boolean apply(CharSequence t) {
        	return pattern.matcher(t).find();
        }

        @Override
        public int hashCode() {
            // Pattern uses Object.hashCode, so we have to reach
            // inside to build a hashCode consistent with equals.

            return Objects.hashCode(pattern.pattern(), pattern.flags());
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (obj instanceof ContainsPatternPredicate) {
            ContainsPatternPredicate that = (ContainsPatternPredicate) obj;

            // Pattern uses Object (identity) equality, so we have to reach
            // inside to compare individual fields.
            return Objects.equal(pattern.pattern(), that.pattern.pattern())
            	&& pattern.flags() == that.pattern.flags();
            }
            return false;
    	}

        @Override
        public String toString() {
            String patternString =
            MoreObjects.toStringHelper(pattern)
            .add("pattern", pattern.pattern())
            .add("pattern.flags", pattern.flags())
            .toString();
            return "Predicates.contains(" + patternString + ")";
        }

        private static final long serialVersionUID = 0;
  	}

    /** @see Predicates#containsPattern(String) */
    @GwtIncompatible // Only used by other GWT-incompatible code.
    private static class ContainsPatternFromStringPredicate extends ContainsPatternPredicate {

        ContainsPatternFromStringPredicate(String string) {
        	super(Platform.compilePattern(string));
        }

        @Override
        public String toString() {
        	return "Predicates.containsPattern(" + pattern.pattern() + ")";
        }

        private static final long serialVersionUID = 0;
    }

    private static <T> List<Predicate<? super T>> asList(
            Predicate<? super T> first, Predicate<? super T> second) {
        // TODO(kevinb): understand why we still get a warning despite @SafeVarargs!
        return Arrays.<Predicate<? super T>>asList(first, second);
    }
	
	
    private static <T> List<T> defensiveCopy(T... array) {
    	return defensiveCopy(Arrays.asList(array));
    }
	// 引用拷貝,淺拷貝
    static <T> List<T> defensiveCopy(Iterable<T> iterable) {
        ArrayList<T> list = new ArrayList<T>();
        for (T element : iterable) {
        	list.add(checkNotNull(element));
        }
        return list;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章