Lambda表达式
JDK8的新特性
1、Lambda表达式(函数式编程)
2、Stream流(Lambda的实际运行之一)
函数式编程思想概述
函数有输入量,计算过程,输出量(y=xx+2x+2),函数式编程思想,以一种尽量简单的格式,简化面向对象中复杂的格式,面向对象强调的是以何种形式去做,而函数式编程思想强调的是拿什么东西做什么事情,而不强调以何种形式去做。
冗余的Runnable代码体验
public class TestRunnableDemo {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.printf(Thread.currentThread().getName());
}
}).start();
//分析:传统的Runnable实现方式冗余代码
//1、为了避免创建新类 我们不得不去搞一个匿名内部类
//2、为了迎合面向对象语法,我们只能用Runnable的实现类
//3、重写时,方法必须和接口中的一模一样
//4、我们真正需要的就是一句任务代码【System.out.printf(Thread.currentThread().getName());】
}
}
函数式编程Lambda
public class TestRunnableDemo {
public static void main(String[] args) {
//体验Lambda表达式写法
new Thread(()->{ System.out.printf(Thread.currentThread().getName());}).start();
}
}
Lambda格式
标准格式
(参数列表)->{方法体;retunrn 返回值;}
(参数列表)相当于方法的参数,如果没有参数,那么只写小括号即可。
->:固定用法,代码拿着前面的参数,去做什么事情。
{}:大括号先写计算过程,如果有返回值return 返回值,如果没有返回值return可以省略。
带参数的和返回值的
代码实现:
public class CompareTest {
public static void main(String[] args) {
//比较器
Integer[] nums = {4, 5, 2, 1, 8, 9, 6};
//对数组排序
//Arrays.sort(nums);升序
//降序 使用比较器
//Arrays.sort(nums, new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// return o2 - o1;
// }
//});
//打印数组
//System.out.println(Arrays.toString(nums));
//使用表达式改写
Arrays.sort(nums,(Integer o1,Integer o2)->{return o2-o1;});
}
}
省略格式
1、参数类型可以省略
2、如果参数只有一个,那么小括号可以省略
3、如果大括号中的代码可以写成一句代码,【那么大括号,return关键字和分号可以同时省略】
代码实现一:
//体验Lambda表达式写法
new Thread(()->{ System.out.printf(Thread.currentThread().getName());}).start();
//省略格式
new Thread(()-> System.out.printf(Thread.currentThread().getName())).start();
代码实现二:
//使用表达式改写
Arrays.sort(nums, (Integer o1, Integer o2) -> {
return o2 - o1;
});
//省略格式
Arrays.sort(nums, (o1, o2) -> o2 - o1);
}
Lambda的前提条件
1、Lambda只能用于替换,有且仅有一个抽象方法的接口和匿名内部类对象,这种接口称为函数式接口
2、Lambda具有上下文推断的功能,所以我们才会出现Lambda的省略格式。
Stream流
传统的循环遍历的弊端
Lambda注重于做什么,而传统的面向对象注重于怎么做。为了解决这种复杂形式,引入了Stream流式思想。
Stream示例
public class StreamTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("赵四");
list.add("刘三");
list.add("赵敏");
//选出以赵开头的名字
list.stream().filter(s -> s.startsWith("赵"));
//选出名字为两个字的名字
list.stream().filter(s -> s.startsWith("赵")).filter(s -> s.length() == 2).forEach(s -> System.out.println(s));
}
}
获取流的方式
Collection集合获取流
Stream <E> stream=集合对象.stream();
Map集合不能直接获取流,但是可以间接获取流
map.keySet().stream();//获取map的键流
map.values().stream();//获取map的值流
map.entrySet().stream();//获取键值对的流
数组获取流
Stream<数据类型> s=Stream.of(数据类型...变量名)
Stream流中的常用方法
1、foreach逐一处理
//1、获取一个流
Stream<String> stream = Stream.of("jack", "jkl", "sda");
//foreach逐一处理
stream.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//stream.forEach(stream -> System.out.println(stream));
2、count统计个数
//2、统计个数
long count = stream.count();
System.out.println(count);
3、filter过滤
//3、filter过滤
Stream<String> stream1 = stream.filter(new Predicate<String>() {
@Override
public boolean test(String s) {//会自动将流中的元素传入
//我们只想要长度大于3的字符串,返回的依旧是流
//if (s.length() > 3) {
// return true;
//}
return s.length() > 3;
}
});
//省略形式,使用Lambda
Stream<String> stream2 = stream.filter(s -> s.length() > 3);
4、limit取用前几个
//4、limit,限制,取前几个
Stream<String> limit = stream.limit(3);
limit.forEach(s -> System.out.println(limit));//打印一下
5、skip跳过前几个
//5、skip,跳过前几个
Stream<String> skip = stream.skip(2);
skip.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//System.out.println(skip);
// skip.forEach(s -> System.out.println(s));
}
6、map映射
是将流中每个元素,经过某种算法,变成另外一个元素
7、concat组合
静态方法:public staticStream concat(Stream s1,Stream s2)
//7、组合
Stream<String> stream2 = Stream.of("rte");
Stream<String> concat = Stream.concat(stream, stream2);
concat.forEach(s -> System.out.println(s));
}
注意:
如果是两个以上的流的合并,需要两两合并。
如果两个流的泛型不一致也可以合并,合并后的新流的泛型是他们的父类,或者是object
总结,函数拼接和终结方法
函数拼接方法:由于这种方法返回的还是流对象,所以支持链式编程
调用该方法后,返回的还是一个流对象。有 filter、limit、skip、map、concat
终结方法:由于终结方法没有返回值,所以不支持链式编程。有forEach,count
Stream综合案例
收集Stream结果
收集到集合中
调用collect()方法即可
代码实现:
Stream<String> stream2 = Stream.of("rte","黄");
List<String> collect = stream2.collect(Collectors.toList());
System.out.println(collect);
收集到数组中
流的toArray()方法
代码实现:
Stream<String> stream2 = Stream.of("rte","黄");
Object[] array = stream2.toArray();
System.out.println(array);
注意:
一个流只能收集一次
如果收集到数组中,默认收集到Object数组
感悟
长风破浪会有时,直挂云帆济沧海!