系列文章目录
第一章 万事万物皆对象
第二章 java构造器
第三章 java访问权限
第四章 java初始化
第五章 java继承
第六章 java重载与重写
第七章 java接口和抽象类
第八章 java数组
第九章 java内部类
第十章 java时间操作
第十一章 final关键字
第十二章 java字符串
第十三章 java异常
第十四章 java泛型
第十五章 java IO操作
第十六章 java NIO操作
第十七章 java zip压缩
第十八章 java反射
第十九章 java反射之Type接口
第二十章 java8流式操作
第二十一章 java8函数式编程
原文链接 https://zhhll.icu/2020/java基础/java8/1.java Stream操作/
Stream又称为流,可以将集合转换为一种流,对集合中的每个元素进行一系列的流式操作,流并不存储元素,对流的操作也不会修改数据源
数据源 ------转换为–》流----》进行中间操作----》终止操作
多个中间操作可以连接起来形成一个流水线,除非流水线触发终止操作,否则中间操作不会执行任何处理,在终止操作时一次性全部处理
使用stream()或者parallelStream()方法将集合转为流
可以使用Stream.generate来生成流,产生一个无限流,通过反复调用函数来生成流
Stream<String> stream = Stream.generate(()->"Echo");
也可以使用Stream.of来生成Stream,产生一个给定值的流
Stream<String> stream1 = Stream.of("hello", "java8");
可以用Stream.empty生成一个不包含任何元素的流
Stream<Object> empty = Stream.empty();
可以使用Arrays.stream根据数据来生成流
Stream<String> stream2 = Arrays.stream(new String[]{"hello", "java8"});
过滤操作,只返回为true(满足Predicate断言条件)的数据
// filter方法接收的是Predicate
Stream<T> filter(Predicate<? super T> predicate);
/**
* filter 接收lambda,从流中排除某些元素
*/
public static void testFilter(){
// 中间操作
// 使用的Predicate boolean test(T t);
Stream<String> stream = list.stream()
.filter(e ->
{
System.out.println("filter中间操作");
return e.equals("张三");
}
);
// 这时中间操作还没有执行执行
System.out.println("----中间操作结束----");
//终止操作:一次执行全部操作
stream.forEach(
System.out::println
);
}
去重
/**
* distinct 筛选,通过流所生成元素的hashCode()和equals()方法去重
*/
public static void testDistinct(){
list.stream().distinct().forEach(System.out::println);
}
返回前n个元素
/**
* limit 截断流,使其元素不超过给定数量
*/
public static void testLimit(){
list.stream().limit(2).forEach(System.out::println);
}
去除(跳过)前n个元素
/**
* skip 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回空流
*/
public static void testSkip(){
list.stream().skip(2).forEach(System.out::println);
}
public static void testLimitAndSkip(){
System.out.println("--------先limit再skip---------");
list.stream().limit(2).skip(1).forEach(System.out::println);
System.out.println("--------先skip再limit---------");
list.stream().skip(1).limit(2).forEach(System.out::println);
}
注意:在limit和skip搭配使用的时候,两个的顺序不同会导致结果不同
排序可以有两种排序方式,第一种是进行排序的类要实现Comparable接口,第二种是在自己实现一个Comparator接口
/**
* sorted()自然排序 Comparable 所要排序的类必须实现Comparable接口
*/
public static void test(){
list.stream().map(User::getAge).sorted().forEach(System.out::println);
}
/**
* sorted(Comparator com) 定制排序(Comparator)
*/
public static void test1(){
list.stream().sorted(
(o1, o2) -> {
if(o1.getAge() > o2.getAge()){
return -1;
}
return 0;
}
).forEach(System.out::println);
}
转换功能,将mapper应用于当前流中的所有元素所产生的结果
// map方法接收的参数为Function接口
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
/**
* map 接收lambda,将元素转换为其他形式或提取信息。接收一个函数作为函数,
* 该函数会被应用到每个元素上,并将其映射成一个新的元素
*
* 如果函数返回的是一个流的话,使用map会使得流里存储着多个流
*/
public static void testMap(){
// 使用Function R apply(T t);
list.stream().map(User::getAge).forEach(System.out::println);
}
将多个Stream合并成一个Stream,将mapper应用于当前流中所有元素所产生的结果连接到一起(每一个结果都是一个流)
// flatMap方法接收的参数为Function接口
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
/**
* flatMap 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
*
* 如果函数返回的是一个流,使用flatMap会使得函数返回的流中的元素放到一个流中
*/
public static void testFlatMap(){
// 要求Function R apply(T t);中返回值是一个Stream流
List<String> add = new ArrayList<>();
add.add("添加元素");
List<String> strings = list.stream().map(User::getName).collect(Collectors.toList());
strings.stream().flatMap(
TestStreamApi1::joinStream
).forEach(System.out::println);
}
流中所有元素都要匹配给定的条件为true,否则为false 相当于且
/**
* allMatch测试
*/
public static void testAllMatch(){
boolean isSex = list.stream().allMatch(
l -> l.getSex() == 0
);
System.out.println(isSex);
}
流中有任意一条数据匹配给定的条件为true,否则为false 相当于并
/**
* anyMatch测试
*/
public static void testAnyMatch(){
boolean isSex = list.stream().anyMatch(
l -> l.getSex() == 0
);
System.out.println(isSex);
}
流中所有的数据都不匹配给定条件时为true,否则为false 相当于非
/**
* noneMatch测试
*/
public static void testNoneMatch(){
boolean isSex = list.stream().noneMatch(
l -> l.getSex() == 0
);
System.out.println(isSex);
}
找到第一个元素
/**
* findFirst测试
*/
public static void testFindFirst(){
User user = list.stream().sorted(
((o1, o2) -> {
if(o1.getAge() > o2.getAge()){
return -1;
} else if(o1.getAge() < o2.getAge()){
return 1;
}
return 0;
})
).findFirst().get();
System.out.println(user);
}
找到其中任意一个元素
/**
* findAny测试
*/
public static void testFindAny(){
User user = list.stream().filter(
l -> l.getSex() == 0
).findAny().get();
System.out.println(user);
}
返回流中元素的数量
/**
* count测试
*/
public static void testCount(){
long count = list.stream().count();
System.out.println(count);
}
返回流中根据比较之后的最大值元素
// max方法接收的是Comparator接口
Optional<T> max(Comparator<? super T> comparator);
/**
* max测试
*/
public static void testMax(){
User user = list.stream().max(
((o1, o2) -> {
if(o1.getAge() > o2.getAge()){
return 1;
} else if(o1.getAge() < o2.getAge()){
return -1;
}
return 0;
})
).get();
System.out.println(user);
}
返回流中根据比较之后的最小值元素
// min方法接收的是Comparator接口
Optional<T> min(Comparator<? super T> comparator);
/**
* min测试
*/
public static void testMin(){
User user = list.stream().min(
((o1, o2) -> {
if(o1.getAge() > o2.getAge()){
return 1;
} else if(o1.getAge() < o2.getAge()){
return -1;
}
return 0;
})
).get();
System.out.println(user);
}
使用reduce来进行运算,从一组值中生成一个值
// reduce方法接收的是BinaryOperator接口(二元运算操作)
Optional<T> reduce(BinaryOperator<T> accumulator);
/**
* 归约 将流中元素反复结合起来,得到一个值
* reduce(T identity, BinaryOperator accumulator) /BinaryOperator accumulator/U identity,
* BiFunction accumulator,
* BinaryOperator combiner
*/
public static void testReduce(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
// BinaryOperator 二元运算 R apply(T t, U u);
int sum = list.stream().reduce((x, y) -> x+y).get();
System.out.println(sum);
}
根据不同的收集器collect(Collectors.toList())、collect(Collectors.toSet())来返回不同的集合
/**
* 收集 collect -- 将流转换为其他形式 接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
*/
public static void testCollect(){
// Collector是一个接口 有一个Collectors提供了各种转换方式
List<String> strings = list.stream().map(User::getName).collect(Collectors.toList());
System.out.println(strings);
}
当初java8打着去除空指针的旗号推出了Optional,但是很多人用起来发现其实和判断是否为null没什么区别
其实有效地使用Optional的关键是要使用这样的方法:它的值不存在的情况下产生一个可替代物,而只有在值存在的情况下才会使用这个值
// 提供一个默认值,在Optional为空的时候使用默认值
public T orElse(T other)
// 提供一个默认值,在Optional为空的时候使用默认值(调用other来产生默认值)
public T orElseGet(Supplier<? extends T> other)
// 提供一个默认值,在Optional为空的时候抛出异常(调用exceptionSupplier来产生异常)
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
// 如果Optional不为空,将值传给consumer
public void ifPresent(Consumer<? super T> consumer)
// 产生该Optional的值传递给mapper后的结果,只要这个Optional不为空且结果不为null,否则产生一个空Optional
public<U> Optional<U> map(Function<? super T, ? extends U> mapper)
而对于有些人总是使用optional.isPresent()来判断是不是空,其实和之前判断value != null没什么区别,这种情况使用Optional没有任何好处