Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。 和匿名内部类相似,可以简化匿名内部类的写法,只作用于只有一个抽象方法的接口;
javaComparator<Integer> comparator = (Integer a, Integer b) -> {
return a - b;
};
//可根据Lambda的简化原则,进行简化
Comparator<Integer> comparator = (a, b) -> a - b;
lambda
表达式只能用于创建接口对象,并且该接口只能有一个抽象方法;lambda
表达式中使用外部的局部变量,会默认添加final
,不能二次赋值;所谓函数式接口,指的是只有一个抽象方法的接口。 函数式接口可以被隐式转换为Lambda表达式。 函数式接口可以用@FunctionalInterface**注解标识。
消费,只有输入没有输出。
javaConsumer<String> c1 = n -> System.out.print("<"+n+">");
Consumer<String> c2 = n -> System.out.print("["+n+"]");
c1.accept("test01"); //打印 <test01>
//andThen(c2):按Consumer顺序连续消费
c1.andThen(c2).accept("test01"); //打印<test01>[test01]
函数,既有输入也有输出。
javaFunction<String, String> f1 = s -> s + "+";
Function<String, String> f2 = s -> s + "-";
System.out.println(f1.apply("test01")); //打印:test01+
//连续调用,将f1处理的结果给f2调用
System.out.println(f1.andThen(f2).apply("test01")); //打印:test01+-
//连续调用(反向),将f2处理的结果给f1调用
System.out.println(f1.compose(f2).apply("test01")); //打印:test01-+
//identity():返回一个将输入原样返回的Function
System.out.println(Function.identity().apply("test01")); //打印:test01
判断,有输入返回值为boolean
。
javaPredicate<String> p1 = o -> o.equals("test");
Predicate<String> p2 = o -> o.startsWith("t");
System.out.println(p1.test("test01")); //打印:false
//取反
System.out.println(p1.negate().test("test01")); //打印:true
//与运算
System.out.println(p1.and(p2).test("test01")); //打印:false
//或运算
System.out.println(p1.or(p2).test("test01")); //打印:true
//判断是否相等
System.out.println(Predicate.isEqual("test01").test("test01")); //打印:true
供应,没有输入但有输出
java//引用了Date构造器;特点是没有参数
Supplier<Date> supplier = Date::new;
//调用了get(),相当于调用了new Date(),返回新对象
Date date = supplier.get();
System.out.println(date);
Stream
可以对多个元素进行一系列的操作,也可以支持对某些操作进行并发处理。
java//空的Stream
Stream<Integer> st1 = Stream.empty();
//根据元素创建
Stream<Integer> st2 = Stream.of(1, 3, 5, 7, 9);
//根据集合创建
List<Integer> list = Arrays.asList(1, 3, 5, 7, 9);
Stream<Integer> st3 = list.stream(); //串行,单线程处理
Stream<Integer> st4 = list.parallelStream(); //并行,多线程处理
//生成数据创建,这里是随机生成10个[0,99)的数;
Stream<Integer> st5 = Stream.generate(() -> (int) (Math.random() * 100)).limit(10);
javaList<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
integerList.stream().filter(n -> n%2 == 0).forEach(System.out::println); //筛选
integerList.stream().distinct().forEach(System.out::println); //去重
integerList.stream().limit(3).forEach(System.out::println); //只要前n个
integerList.stream().skip(2).forEach(System.out::println); //舍去前n个
integerList.stream().sorted().forEach(System.out::println); //排序
//对每个元素进行同一处理,将每个的处理结果作为新的stream
integerList.stream().map(n -> n*2).forEach(System.out::println);
//返回值与map()不同,返回一个Stream,将所有返回的stream合成一个新的stream
integerList.stream().flatMap(n -> Stream.of(n-1,n, n+1)).forEach(System.out::println);
javaStream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
//统计
System.out.println( stream.count() ); //计数
System.out.println( stream.max((a, b) -> a - b).get() ); //最大值
System.out.println( stream.min((a, b) -> a - b).get() ); //最小值
System.out.println( stream.reduce((a, b) -> a + b).get() ); //将每次操作的返回值和下一个元素进行操作,这里等同于求和
//对stream的数据进行汇总
IntSummaryStatistics stat = stream.mapToInt(n -> n).summaryStatistics();
System.out.println( stat.getSum() );
System.out.println( stat.getMax() );
System.out.println( stat.getMin() );
System.out.println( stat.getAverage() );
//判断
System.out.println( stream.anyMatch(n -> n > 10) ); //满足任何一个就返回true
System.out.println( stream.allMatch(n -> n > 10) ); //全部满足才返回true
System.out.println( stream.noneMatch(n -> n > 10) ); //全部不满足才返回true
//转换
int[] ints = stream.mapToInt(n -> n).toArray(); //转int数组
//通过切换Collectors的静态方法,可实现不同类型的转换
List<Integer> list = stream.collect(Collectors.toList()); //转list
Set<Integer> set = stream.collect(Collectors.toSet()); //转set
Map<Integer, Integer> map = stream.collect(Collectors.toMap(n -> n, n -> n)); //转map
//连接字符串,必须是Stream<String>
String str = stream.map(String::valueOf).collect(Collectors.joining());
//Integer集合和String集合的互转,其他类型的转化只需要换.map的函数即可
List<String> stringList = stream.map(String::valueOf).collect(Collectors.toList());
List<Integer> collect = stringList.stream().map(Integer::parseInt).collect(Collectors.toList());
分组排序,根据某个属性值(日期、字符串等)进行分组,若分组前进行了排序,则分组后每个组中的元素也是有序的;
java@Data
@NoArgsConstructor
@AllArgsConstructor
private static class User {
private String name;
private Integer age;
private String position;
}
public static void main(String[] args) {
User zs = new User("张三", 30, "老板");
User ls = new User("李四", 21, "员工");
User wr = new User("王二", 22, "员工");
Stream<User> stream = Stream.of(zs, ls, wr);
LinkedHashMap<String, List<User>> groupUser = stream.sorted(Comparator.comparingInt(User::getAge))
.collect(Collectors.groupingBy(User::getPosition, LinkedHashMap::new, Collectors.toList()));
groupUser.forEach((k, v) -> {
System.out.println(k);
v.forEach(System.out::println);
});
}
//打印:
//员工
//DateUtilTest.User(name=李四, age=21, position=员工)
//DateUtilTest.User(name=王二, age=22, position=员工)
//老板
//DateUtilTest.User(name=张三, age=30, position=老板)
在函数式编程时,空指针异常非常容易犯,Optional
就主要解决这个问题。
java//of()不会检查传入的对象是否为空;而ofNullable()会检测是否为null,若为null,会创建一个空的Optional
Optional<String[]> o1 = Optional.empty(); //创建空的Optional
Optional<String[]> o2 = Optional.of(args);
Optional<String[]> o3 = Optional.ofNullable(args);
javaoptional.isPresent(); //判断值是否为空
optional.ifPresent(System.out::println); //若optional不为空,则进行消费,比如添加到集合等;
Optional<Integer> o1 = optional.map(n -> n * 2); //若optional不为空,则将执行函数后的返回值封装为Optional返回,否则返回Optional.empty();
Optional<Integer> o2 = optional.filter(n -> n > 5); //空的optional和判断为false都返回Optional.empty(),判断为true则返回this;
Integer i1 = optional.get(); //获取值,若optional为空,则抛出异常;
Integer i2 = optional.orElse(4); //若optional不为空,则返回它的值,否则返回传入的值;
Integer i3 = optional.orElseGet(() -> new Random().nextInt(10)); //默认值从传入的函数中获取,既动态的默认值;
Integer i4 = optional.orElseThrow(() -> new NullPointerException()); //若为空则抛出指定的异常
本文作者:牟相波
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!