概述
为什么要学?
- 能看懂公司的代码
- 大数量下处理集合效率高
- 代码可读性高
- 消灭嵌套地狱
List<Boook> collect = authors.stream()
.distinct()
.filter(author -> author.getAge() < 18)
.map(author -> author.getBooks())
.flatMap(Collection::stream)
.filter(book -> book.getScore() > 70)
.distinct()
.collect(Collectors.toList());
System.out.println(collect);
函数式编程思想
概念
面向对象思想需要关注用什么对象完成什么事情。而函数式编程思想就类似于我们数学中的函数。它主要关注的是对数据进行了什么操作。
优点
- 代码简洁,开发快速
- 接近自然语言,易于理解
- 易于“并发编程”
Lambda表达式
概述
Lambda是JDK8中一个语法糖。可以看成是一种语法糖,他可以对某些匿名内部类的写法进行简化。他是函数式编程思想的一个重要体现。让我们不用关注是什么对象。而是更关注我们对数据进行了什么操作。
核心原则
可推导可省略
基本格式
(参数列表) -> {代码}
例一
我们在创建线程并启动时可以使用匿名内部类的写法
new Thread(new Runnable(){
@Override
public void run(){
System.out.println("hello");
}
}).start();
使用Lambda表达式进行修改,如下:
比如这个,对于匿名内部类写法的线程,直接省略了参数,省略了方法名
new Thread(()->{
System.out.println("hello");
}).start();
例二
匿名内部类调用写法
int i = calculateNum(new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return left + right;
}
});
System.out.println(i);
Lambda写法
int i = calculateNum((int left,int right)->{
return left + right;
});
System.out.println(i);
例三
public static void printNum(IntPredicate predicate){
int[] arr = {1,2,3,4,5,6,7,8,9,10};
for (int i : arr){
if(predicate.test(i)){
System.out.println(i);
}
}
}
匿名内部类调用写法
printNum(new IntPredicate() {
@Override
public boolean test(int value) {
return value %2 == 0;
}
});
lambda表达式写法
printNum((int value)->{
return value %2 ==0 ;
});
Lambda最简
printNum(value -> value %2 == 0 );
例四
public static <R> R typeConver(Function<String,R>function){
String str = "12345";
R result = function.apply(str);
return result;
}
匿名内部类调用写法
public static void main(String[] args) {
Integer integer = typeConver(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.valueOf(s);
}
});
System.out.println(integer);
}
Lambda表达式
public static void main(String[] args) {
Integer integer = typeConver((String s) ->{
return Integer.valueOf(s);
});
System.out.println(integer);
}
Lambda最简
Integer integer = typeConver( s -> Integer.valueOf(s));
System.out.println(integer);
例五
public static void foreachArr(IntConsumer consumer){
int [] arr = {1,2,3,4,5,6,7,8,9,10};
for(int i : arr){
consumer.accept(i);
}
}
匿名内部类调用写法
foreachArr(new IntConsumer() {
@Override
public void accept(int value) {
System.out.println(value);
}
});
Lambda表达式
public static void main(String[] args) {
foreachArr((int value)-> {
System.out.println(value);
});
}
Lambda最简
foreachArr(value-> System.out.println(value));
省略规则
- 参数类型可以省略
- 方法体只有一句代码时大括号return和唯一一句代码的分号可以省略
- 方法只有一个参数时小括号可以省略
- 以上这些规则都记不住也可以省略不记
Stream流
概述
java8的Stream使用的是函数式编程模式,如同他的名字一样,他可以被用来对集合或数组进行链状流式的操作。可以更方便的让我们对集合或数组操作。
Stream流三种方法
-
开始方法
获取stream流对象 -
中间方法
filter:过滤信息
skip:跳过截取
limit:要截取几个
distinct:去重
map:类型转换的!!! -
终结方法
forEach
count
collect:把结果封装起来
需求
这边没有写源码,只有结果,借鉴一下
现在需要打印所有年龄小于18的作家的名字,并且要注意去重
public static void main(String[] args){
List<Author> authors = getAuthors;
authors.stream()
.distinct()
.filter(author -> author.getAge() < 18)
.forEach(author -> System.out.println(author.getName()));
}
常用操作
创建流
单列集合:集合对象.stream()
List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();
数组:Arrays.stream(数组)或者使用Stream.of来创建
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);
Stream<Integer> stream = Stream.of(arr);
举例
获得integer > 2的所有值
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* create by 刘鸿涛
* 2022/9/24 11:25
*/
@SuppressWarnings({"all"})
public class Test {
public static void main(String[] args) {
Integer [] arr = {1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);
stream.distinct()
.filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
return integer > 2;
}
}).forEach(integer -> System.out.println(integer));
}
}
改为Lambda表达式
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* create by 刘鸿涛
* 2022/9/24 11:25
*/
@SuppressWarnings({"all"})
public class Test {
public static void main(String[] args) {
Integer [] arr = {1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);
stream.distinct()
.filter(integer -> integer > 2)
.forEach(integer -> System.out.println(integer));
}
}
双列集合:转换成单列集合后再创建
filter条件为value大于18
forEach输出entry.getKey + entry.getValue,entry是双列值同一统一个对象
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* create by 刘鸿涛
* 2022/9/24 11:25
*/
@SuppressWarnings({"all"})
public class Test {
public static void main(String[] args) {
test03();
}
private static void test03(){
Map<String, Integer> map = new HashMap<>();
map.put("蜡笔小新",19);
map.put("黑子",17);
map.put("日向翔阳",16);
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
Stream<Map.Entry<String, Integer>> stream = entrySet.stream();
stream.filter(new Predicate<Map.Entry<String, Integer>>() {
@Override
public boolean test(Map.Entry<String, Integer> entry) {
return entry.getValue() > 18;
}
}).forEach(new Consumer<Map.Entry<String, Integer>>() {
@Override
public void accept(Map.Entry<String, Integer> entry) {
System.out.println(entry.getKey() + "===" + entry.getValue());
}
});
}
}
debug分析
创建流
Map<String,Integer> map = new HashMap<>();
map.put("蜡笔小新",19);
map.put("黑子",17);
map.put("日向翱翔",16);
Stream <Map.Entry<String,Integer>> stream = map.entrySet().stream();