Java 8 中的谓词

筛选隐藏文件


/**
* 筛选隐藏文件
* 
* @param path
* @return
*/
File[] listHiddenFiles2(String path) {
return new File(path).listFiles(File::isHidden);
}

filter

谓词使用代码示例:

https://github.com/java-8/java8-impatient/blob/master/src/main/java/study/java8/lambda/LambdaDemo.java

/**
 * LambdaDemo.java
 */
package study.java8.lambda;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;

/**
 * @author jack 2016年8月18日 下午2:16:53
 */
public class LambdaDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {

        List<Integer> nums = Arrays.asList(1,
                                           23,
                                           4,
                                           56,
                                           7,
                                           8,
                                           10);
        // 用stream api
        nums.stream()
            .sorted()
            .forEach(System.out::println);
        // lambda表达式本质上也是Collections.sort方法
        nums.sort((e1, e2) -> e1.compareTo(e2));
        nums.forEach(System.out::println);

        // 内部类,Collections.sort方法
        nums.sort(new Comparator<Integer>() {

            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        });

        List<String> languages = Arrays.asList("Java",
                                               "Scala",
                                               "C++",
                                               "Haskell",
                                               "Lisp");

        System.out.println("Languages which starts with J :");
        filter(languages,
               (str) -> str.startsWith("J"));

        System.out.println("Languages which ends with a ");
        filter(languages,
               (str) -> str.endsWith("a"));

        System.out.println("Print all languages :");
        filter(languages,
               (str) -> true);

        System.out.println("Print no language : ");
        filter(languages,
               (str) -> false);

        System.out.println("Print language whose length greater than 4:");
        filter(languages,
               (str) -> str.length() > 4);

    }

    public static void filter(List<String> names, Predicate<String> condition) {
        for (String name : names) {
            if (condition.test(name)) {
                System.out.println(name + " ");
            }
        }
    }

}

:: 与 ->

java8函数式编程中引进了::与->这两个关键字.

这个双冒号, 是传递函数的.由编译器解释,而不是由JVM运行时. 具体实现原理可以通过分析class文件看.

代码示例:

https://github.com/java-8/java8-impatient/blob/master/src/main/java/study/java8/fp/FunctionalInterfaceDemo.java

/**
 * FunctionalInterfaceDemo.java
 */
package study.java8.fp;

/**
 * @author jack 2016年8月16日 下午3:57:58
 */
public class FunctionalInterfaceDemo {
    String startWith(String s) {
        return s.valueOf(s.charAt(0));
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        FunctionalInterfaceDemo DoubleColons = new FunctionalInterfaceDemo();
        Converter<String, String> converter = DoubleColons::startWith;

        String cc = converter.convert("Scala");
        System.out.println(cc);

    }

}

@FunctionalInterface
interface Converter<F, T> {
    T convert(F from);
}

注解@FunctionalInterface

函数式接口就是只包含一个函数方法的接口.一般用@FunctionalInterface这个注解标记.

当然, 这个接口里面可以包含默认方法, 静态方法等.

@FunctionalInterface
public interface FileFilter {

    /**
     * Tests whether or not the specified abstract pathname should be
     * included in a pathname list.
     *
     * @param  pathname  The abstract pathname to be tested
     * @return  <code>true</code> if and only if <code>pathname</code>
     *          should be included
     */
    boolean accept(File pathname);
}

Predicate接口

Predicate和Consumer接口的test()和accept()方法都接受一个泛型参数。不同的是test()方法进行某些逻辑判断并返回一个boolean值,而accept()接受并改变某个对象的内部值。

/**
 * AppleFilter.java
 */
package study.java8.fp;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * @author jack 2016年8月10日 下午5:30:53
 */
public class AppleFilter {

    public static List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> p) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (p.test(apple)) {
                result.add(apple);
            }
        }
        return result;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        List<Apple> inventory = Arrays.asList(new Apple(80, "green"), new Apple(155, "green"), new Apple(120, "red"));

        List<Apple> greenApples = filterApples(inventory, AppleFilter::isGreenApple);
        System.out.println(greenApples);

        List<Apple> heavyApples = filterApples(inventory, AppleFilter::isHeavyApple);
        System.out.println(heavyApples);

        List<Apple> greenApples2 = filterApples(inventory, (Apple a) -> isGreenApple(a));
        System.out.println(greenApples2);

        List<Apple> heavyApples2 = filterApples(inventory, (Apple a) -> isHeavyApple(a));
        System.out.println(heavyApples2);

        List<Apple> weirdApples = filterApples(inventory,
                (Apple a) -> a.getWeight() < 80 || "brown".equals(a.getColor()));
        System.out.println(weirdApples);
    }

    public static List<Apple> filterGreenApples(List<Apple> inventory) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (isGreenApple(apple)) {
                result.add(apple);
            }
        }
        return result;
    }

    public static List<Apple> filterHeavyApples(List<Apple> inventory) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (isHeavyApple(apple)) {
                result.add(apple);
            }
        }
        return result;
    }

    /////////////////////////////////////////////////

    public static boolean isGreenApple(Apple apple) {
        return "green".equals(apple.getColor());
    }

    public static boolean isHeavyApple(Apple apple) {
        return apple.getWeight() > 150;
    }

    public static class Apple {
        private int weight = 0;
        private String color = "";

        public Apple(int weight, String color) {
            this.weight = weight;
            this.color = color;
        }

        public Integer getWeight() {
            return weight;
        }

        public void setWeight(Integer weight) {
            this.weight = weight;
        }

        public String getColor() {
            return color;
        }

        public void setColor(String color) {
            this.color = color;
        }

        public String toString() {
            return "Apple{" + "color='" + color + '\'' + ", weight=" + weight + '}';
        }
    }

}

这里的::指向Predictable接口:

package java.util.function;
import java.util.Objects;
/**
 * Represents a predicate (boolean-valued function) of one argument.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #test(Object)}.
 *
 * @param <T> the type of the input to the predicate
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);

    /**
     * Returns a composed predicate that represents a short-circuiting logical
     * AND of this predicate and another.  When evaluating the composed
     * predicate, if this predicate is {@code false}, then the {@code other}
     * predicate is not evaluated.
     *
     * <p>Any exceptions thrown during evaluation of either predicate are relayed
     * to the caller; if evaluation of this predicate throws an exception, the
     * {@code other} predicate will not be evaluated.
     *
     * @param other a predicate that will be logically-ANDed with this
     *              predicate
     * @return a composed predicate that represents the short-circuiting logical
     * AND of this predicate and the {@code other} predicate
     * @throws NullPointerException if other is null
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    /**
     * Returns a predicate that represents the logical negation of this
     * predicate.
     *
     * @return a predicate that represents the logical negation of this
     * predicate
     */
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    /**
     * Returns a composed predicate that represents a short-circuiting logical
     * OR of this predicate and another.  When evaluating the composed
     * predicate, if this predicate is {@code true}, then the {@code other}
     * predicate is not evaluated.
     *
     * <p>Any exceptions thrown during evaluation of either predicate are relayed
     * to the caller; if evaluation of this predicate throws an exception, the
     * {@code other} predicate will not be evaluated.
     *
     * @param other a predicate that will be logically-ORed with this
     *              predicate
     * @return a composed predicate that represents the short-circuiting logical
     * OR of this predicate and the {@code other} predicate
     * @throws NullPointerException if other is null
     */
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    /**
     * Returns a predicate that tests if two arguments are equal according
     * to {@link Objects#equals(Object, Object)}.
     *
     * @param <T> the type of arguments to the predicate
     * @param targetRef the object reference with which to compare for equality,
     *               which may be {@code null}
     * @return a predicate that tests if two arguments are equal according
     * to {@link Objects#equals(Object, Object)}
     */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

results matching ""

    No results matching ""