java 设计

Java8 新特性之 Lambda 表达式

2020-01-15  本文已影响0人  LANSHENGYANG

Lambda表达式

一. 行为参数化

/**
 * 苹果实体
 *
 * @author zhenchao.wang 2016-09-17 12:49
 * @version 1.0.0
 */
public class Apple {

    /** 编号 */
    private long id;

    /** 颜色 */
    private Color color;

    /** 重量 */
    private float weight;

    /** 产地 */
    private String origin;

    public Apple() {
    }

    public Apple(long id, Color color, float weight, String origin) {
        this.id = id;
        this.color = color;
        this.weight = weight;
        this.origin = origin;
    }
    // 省略getter和setter
}
/**
 * 筛选绿苹果
 *
 * @param apples
 * @return
 */
public static List<Apple> filterGreenApples(List<Apple> apples) {
    List<Apple> filterApples = new ArrayList<>();
    for (final Apple apple : apples) {
        if (Color.GREEN.equals(apple.getColor())) {
            filterApples.add(apple);
        }
    }
    return filterApples;
}
/**
 * 筛选红苹果
 *
 * @param apples
 * @return
 */
public static List<Apple> filterRedApples(List<Apple> apples) {
    List<Apple> filterApples = new ArrayList<>();
    for (final Apple apple : apples) {
        if (Color.RED.equals(apple.getColor())) {
            filterApples.add(apple);
        }
    }
    return filterApples;
}
/**
 * 自定义筛选颜色
 *
 * @param apples
 * @param color
 * @return
 */
public static List<Apple> filterApplesByColor(List<Apple> apples, Color color) {
    List<Apple> filterApples = new ArrayList<>();
    for (final Apple apple : apples) {
        if (color.equals(apple.getColor())) {
            filterApples.add(apple);
        }
    }
    return filterApples;
}
/**
 * 筛选指定颜色,且重要符合要求
 *
 * @param apples
 * @param color
 * @param weight
 * @return
 */
public static List<Apple> filterApplesByColorAndWeight(List<Apple> apples, Color color, float weight) {
    List<Apple> filterApples = new ArrayList<>();
    for (final Apple apple : apples) {
        if (color.equals(apple.getColor()) && apple.getWeight() >= weight) {
            filterApples.add(apple);
        }
    }
    return filterApples;
}
/**
 * 苹果过滤接口
 *
 * @author zhenchao.wang 2016-09-17 14:21
 * @version 1.0.0
 */
@FunctionalInterface
public interface AppleFilter {

    /**
     * 筛选条件抽象
     *
     * @param apple
     * @return
     */
    boolean accept(Apple apple);

}

/**
 * 将筛选条件封装成接口
 *
 * @param apples
 * @param filter
 * @return
 */
public static List<Apple> filterApplesByAppleFilter(List<Apple> apples, AppleFilter filter) {
    List<Apple> filterApples = new ArrayList<>();
    for (final Apple apple : apples) {
        if (filter.accept(apple)) {
            filterApples.add(apple);
        }
    }
    return filterApples;
}
public static void main(String[] args) {
    List<Apple> apples = new ArrayList<>();

    // 筛选苹果
    List<Apple> filterApples = filterApplesByAppleFilter(apples, new AppleFilter() {
        @Override
        public boolean accept(Apple apple) {
            // 筛选重量大于100g的红苹果
            return Color.RED.equals(apple.getColor()) && apple.getWeight() > 100;
        }
    });
}
// 筛选苹果
List<Apple> filterApples = filterApplesByAppleFilter(apples,
        (Apple apple) -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= 100);

二. lambda表达式定义

格式一: 参数列表 -> 表达式
格式二: 参数列表 -> {表达式集合}
//返回给定字符串的长度,隐含return语句
(String s) -> s.length() 

// 始终返回42的无参方法
() -> 42 

// 包含多行表达式,则用花括号括起来
(int x, int y) -> {
    int z = x * y;
    return x + z;
}

三. 依托于函数式接口使用lambda表达式

/**
 * 苹果过滤接口
 */
@FunctionalInterface
public interface AppleFilter {
    /**
     * 筛选条件抽象
     * @param apple
     * @return
     */
    boolean accept(Apple apple);
}
Predicate<T>
@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);
}
/**
 * 按照指定的条件对集合元素进行过滤
 *
 * @param list
 * @param predicate
 * @param <T>
 * @return
 */
public <T> List<T> filter(List<T> list, Predicate<T> predicate) {
    List<T> newList = new ArrayList<T>();
    for (final T t : list) {
        if (predicate.test(t)) {
            newList.add(t);
        }
    }
    return newList;
}
demo.filter(list, (String str) -> null != str && !str.isEmpty());
Consumer<T>
@FunctionalInterface
public interface Consumer<T> {
    /**
     * Performs this operation on the given argument.
     * @param t the input argument
     */
    void accept(T t);
}
/**
 * 遍历集合,执行自定义行为
 * @param list
 * @param consumer
 * @param <T>
 */
public <T> void filter(List<T> list, Consumer<T> consumer) {
    for (final T t : list) {
        consumer.accept(t);
    }
}
demo.filter(list, (String str) -> {
        if (StringUtils.isNotBlank(str)) {
            System.out.println(str);
        }
    });
Function<T, R>
@FunctionalInterface
public interface Function<T, R> {
    /**
     * Applies this function to the given argument.
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);
}
/**
 * 遍历集合,执行自定义转换操作
 *
 * @param list
 * @param function
 * @param <T>
 * @param <R>
 * @return
 */
public <T, R> List<R> filter(List<T> list, Function<T, R> function) {
    List<R> newList = new ArrayList<R>();
    for (final T t : list) {
        newList.add(function.apply(t));
    }
    return newList;
}
demo.filter(list, (String str) -> Integer.parseInt(str));

使用过程中需要注意的一些事情

类型推断
// 筛选苹果
List<Apple> filterApples = filterApplesByAppleFilter(apples,
        (Apple apple) -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= 100);

// 某些情况下我们甚至可以省略参数类型,编译器会根据上下文正确判断
List<Apple> filterApples = filterApplesByAppleFilter(apples,
        apple -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= 100);
##### 局部变量
int weight = 100;
List<Apple> filterApples = filterApplesByAppleFilter(apples,
        apple -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= weight);

四. 方法引用

/* ... 省略apples的初始化操作 */

// 采用lambda表达式
apples.sort((Apple a, Apple b) -> Float.compare(a.getWeight(), b.getWeight()));

// 采用方法引用
apples.sort(Comparator.comparing(Apple::getWeight));
方法引用通过::将方法隶属和方法自身连接起来,主要分为三类:
静态方法
(args) -> ClassName.staticMethod(args)
转换成
ClassName::staticMethod
参数的实例方法
(args) -> args.instanceMethod()
转换成
ClassName::instanceMethod  // ClassName是args的类型
外部的实例方法
(args) -> ext.instanceMethod(args)
转换成
ext::instanceMethod(args)

转载 http://www.codeceo.com/article/lambda-of-java-8.html

上一篇 下一篇

猜你喜欢

热点阅读