本文共 7180 字,大约阅读时间需要 23 分钟。
一个接口如果只有一个抽象方法,那么这个接口就是一个函数式接口。我们可以使用@FunctionalInterface修饰这个接口,被这个注解修饰的接口如果有多个抽象方法,那么编译是不会通过的。
例如:
package com.lambda;@FunctionalInterfacepublic interface MyFunctionalInterface { void method();} 假设Demo类中的show方法如下:
package com.lambda;public class Demo { public static void show(MyFunctionalInterface mfi) { mfi.method(); }} 我们有三种写法传递show方法的参数:
MyFunctionalInterface的类的对象;MyFunctionalInterface的抽象方法;例如:
@Testpublic void testLambda() { // 方法1 // Demo.show(new MyFunctionalInterfaceImpl()); // 方法2 Demo.show(new MyFunctionalInterface() { @Override public void method() { System.out.println("这是匿名内部类的写法"); } }); // 方法3 Demo.show(() -> System.out.println("lambda方式的写法"));} 这里举两个例子来感受lambda的简洁:
@Testpublic void testThread() { // 匿名内部类的写法 new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }).start(); // Lambda写法 new Thread(() -> System.out.println(Thread.currentThread().getName())).start();}@Testpublic void testComparator() { String[] strs = { "asdfadf", "asdfasdfasdf", "fasdf", "sdfghdsfghshsdfhsdfg" }; // 匿名内部类写法 Arrays.sort(strs, new Comparator () { @Override public int compare(String o1, String o2) { return o2.length() - o1.length(); } }); System.out.println(Arrays.toString(strs)); // Lambda的写法 Arrays.sort(strs, (s1, s2) -> s1.length() - s2.length()); System.out.println(Arrays.toString(strs));} 如果已经有了现成的方法,有些Lambda表达式是不必要写的,这时候我们就可以把lambda表达式换为方法引用。
例如:
package com.lambda;@FunctionalInterfacepublic interface Printer { void print(String str);} 有如下方法:
private void p(String s, Printer printer) { printer.print(s);} 方法引用:
@Testpublic void testFFYY() { p("测试lambda表达式", (s) -> System.out.println(s)); p("测试方法引用", System.out::println);} 第一行是使用lambda表达式的方法,但是由于lambda的效果和System.out.println()一样,我们可以直接使用方法引用。
常见的方法引用有以下几种:
用于生产一个指定类型的数据,源码如下:
package java.util.function;@FunctionalInterfacepublic interface Supplier{ T get();}
测试案例:
@Testpublic void testSupplier() { Supplier supplier = () -> "测试supplier"; System.out.println(supplier.get());} 用于消费一个指定类型的数据,源码如下:
package java.util.function;import java.util.Objects;@FunctionalInterfacepublic interface Consumer{ void accept(T t); default Consumer andThen(Consumer after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; }}
测试案例:
@Testpublic void testConsumer() { Consumer consumer = (str) -> System.out.println(str); consumer.accept("测试consumer"); consumerAndThen("test andThen in Consumer", str -> System.out.println(str.toUpperCase()), str -> System.out.println(str.toLowerCase()));}private void consumerAndThen(String str, Consumer c1, Consumer c2) { c1.andThen(c2).accept(str);} 用于判断,返回值为boolean,源码如下:
package java.util.function;import java.util.Objects;@FunctionalInterfacepublic interface Predicate{ boolean test(T t); default Predicate and(Predicate other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } default Predicate or(Predicate other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } default Predicate negate() { return (t) -> !test(t); } static Predicate
测试案例:
@Testpublic void testPredicate() { Predicate predicate = (str) -> str.length() > 5; System.out.println(predicate.test("ohhhhhhhh"));} 用于将一种数据类型转换为另一种数据类型,源码如下:
package java.util.function;import java.util.Objects;@FunctionalInterfacepublic interface Function{ R apply(T t); default Function compose(Function before) { Objects.requireNonNull(before); return (T t) -> apply(before.apply(t)); } default Function andThen(Function after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } static Function.identity() { return t -> t; }}
测试案例:
@Testpublic void testFunction() { Function function = (str) -> Integer.valueOf(str) + 10; System.out.println(function.apply("23")); Function function2 = (i) -> String.valueOf(i - 20); String str = function.andThen(function2).apply("78"); System.out.println(str);} Stream是JavaNME中的核心概念,代表一个可读的、可处理的数据流。Stream可以分为终结操作和非终结操作,非终结操作完成后仍然返回一个流对象,支持链式调用。
参数是一个Consumer;
例如:
@Testpublic void testForEach() { List list = new ArrayList<>(); list.add("甲"); list.add("乙"); list.add("丙"); list.add("丁"); list.stream().forEach(item -> System.out.println(item));} 参数是一个Predicate;
例如:
@Testpublic void testFilter() { List list = new ArrayList<>(); list.add("aaa"); list.add("asdf"); list.add("dfsh"); list.add("asdfasd"); list.stream().filter(item -> item.length() < 5) .filter(item -> item.startsWith("a")) .forEach(item -> System.out.println(item));} 参数是一个Function;
例如:
@Testpublic void testMap() { String[] arr = { "17", "234", "567", "16", "23", "34", "345" }; Stream.of(arr).map(item -> Integer.valueOf(item)) .filter(item -> item > 40) .forEach(item -> System.out.println(item));} 统计个数;
例如:
@Testpublic void testCount() { String[] arr = { "17", "234", "567", "16", "23", "34", "345" }; long count = Stream.of(arr).map(item -> Integer.valueOf(item)) .filter(item -> item > 40) .count(); System.out.println(count);} 取流中前n个对象,参数为n;
例如:
@Testpublic void testLimit() { String[] arr = { "17", "234", "567", "16", "23", "34", "345" }; Stream.of(arr).limit(4).forEach(item -> System.out.println(item));} 跳过流中前n个对象,参数为n;
例如:
@Testpublic void testSkip() { String[] arr = { "17", "234", "567", "16", "23", "34", "345" }; Stream.of(arr).skip(4).forEach(item -> System.out.println(item));} 将两个流合并成一个流,参数为两个流;
例如:
@Testpublic void testConcat() { String[] arr = { "17", "234", "567", "16", "23", "34", "345" }; List list = new ArrayList<>(); list.add("aaa"); list.add("asdf"); list.add("dfsh"); list.add("asdfasd"); Stream.concat(Stream.of(arr), list.stream()).forEach(item -> System.out.println(item));} 转载地址:http://dkee.baihongyu.com/