一、lambda表达式
lambda表达式是jdk1.8新特性,lambda表达式实质就是内部实现类(只有一个抽象方法的接口)语法的优化。
1.1规则
接口要求
有且只有一个抽象方法的接口。
使用方法
重写接口的抽象方法时,可写为lambda表达式,如下:
//原写法
public static void main(String[] args) {
Supplier supplier = new Supplier() {
@Override
public Object get() {
return "测试";
}
};
}
//lambda表达式
public static void main(String[] args) {
Supplier supplier =()->"测试";
}
函数式接口
有且只有一个抽象方法的接口,成为函数式接口,但存在default关键字修饰的方法时,也是函数式接口。
我们可以使用@FunctionalInterface注解来自动检测是否满足函数式接口规则。
@FunctionalInterface
interface Add{
int add(Integer a,Integer b);
default int sub(Integer a, Integer b) {
return a-b;
}
}
jdk1.8提供的四大函数式接口
Supplier供给型接口
Supplier supplier = new Supplier() {
@Override
public Object get() {
return null;
}
}
Consumer消费型接口
Consumer<T> Ccnsumer = new Consumer() {
@Override
public void accept(Object o) {
}
};
Function<R,T>函数型接口
public static void main(String[] args) {
Function<R,T> function = new Function<R, T>() {
@Override
public T apply(R r) {
return null;
}
};
}
default关键字
jdk1.8之后新增default关键字,被default修饰的方法会有一个默认实现,不影响lambda表达式的使用,如下:
default修饰的方法需要写方法体,且可以在接口中实现,由此可见,由default修饰的方法在接口中会有默认实现,且可以通过对象调用方法,但省去default关键字就会报错,不满足函数式接口规则。
public static void main(String[] args) {
Add add = (a,b) -> a+b;
System.out.println(add.add(10,11));
System.out.println(add.sub(10,11));
}
@FunctionalInterface
interface Add{
int add(Integer a,Integer b);
default int sub(Integer a, Integer b) {
return 0;
}
}
结果:
21
-1
方法引用
类::实例方法
public static void main(String[] args) {
Comparator<Integer> comparable = (o1, o2) -> o1.compareTo(o2);
//方法引用
Comparator<Integer> comparable = Integer::compareTo;
System.out.println(comparable.compare(17,15));;
}
对象::实例方法
public static void main(String[] args) {
Consumer<String> consumer = s -> System.out.println(s);
//方法引用
PrintStream ps = System.out;
Consumer<String> consumer = ps::println;
consumer.accept("11111111111");
}
类::静态方法
//Integer中
public static int sum(int a, int b) {
return a + b;
}
public static void main(String[] args) {
Add add = (a,b) -> a+b;
//方法引用
Add add = Integer::sum;
System.out.println(add.add(10,20));;
}
二、stream流
2.1常用方法
分为中间方法和结束方法,中间方法返回一个stream流对象,结束方法可封装为对应的集合。
filter方法
filter方法返回一个与条件匹配的中间流对象(符合条件的元素组成的流),所以是一个中间方法,需要使用一个结束方法来进行中间流的内容接收,按需要指定封装成什么集合。
这样理解:filter方法是筛选出满足条件的所有元素。
//stream接口中
Stream<T> filter(Predicate<? super T> predicate);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1,"lv1","lv97979", (byte) 1,new Date()));
list.add(new User(2,"lv2","lv97979", (byte) 1,new Date()));
list.add(new User(3,"lv3","lv97979", (byte) 1,new Date()));
list.add(new User(4,"lv4","lv97979", (byte) 1,new Date()));
Collection<User> collect = list.stream().filter(user -> user.getCustomerId() == 1).collect(Collectors.toList());
System.out.println(collect);
}
map方法
返回一个满足条件的元素中的值的中间流集合,也需要使用一个结束方法封装。
这样理解:map方法是判断元素是否满足某一条件,或者取出流中所有元素的某一属性的值。
该方法不能返回自定义对象的集合,只能返回对应数据类型的键的集合,如下演示:
//stream接口中
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1,"lv1","lv97979", (byte) 1,new Date()));
list.add(new User(2,"lv2","lv97979", (byte) 1,new Date()));
list.add(new User(3,"lv3","lv97979", (byte) 1,new Date()));
list.add(new User(4,"lv4","lv97979", (byte) 1,new Date()));
//返回满足条件的元素的值的集合
//其实可以这样理解:map是键值对的形式存储数据的
//stream流中的map方法只能获取对应条件的键(key),不能获取对应的值(value),如下面的写法,其实可以看做把customerid作为键拿出来
List<Integer> collect = list.stream().map(User::getCustomerId).collect(Collectors.toList());
System.out.println(collect);
//返回自定义对象的集合 此方法是报错的。
List<User> collect = list.stream().map(user -> user.getCustomerId() > 1).collect(Collectors.toList());
System.out.println(collect);
}
//结果
[1, 2, 3, 4]
mapToInt方法
返回类型为int的集合,也可以返回比较为int类型的结果,如下面的两种写法:
这样理解:map方法是判断元素是否满足某一条件且该条件的返回值是int类型,不能是Boolean类型,或者取出流中所有元素的某一属性的值且该值为int类型或能够转化为int的类型。
//stream接口中
IntStream mapToInt(ToIntFunction<? super T> mapper);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1,"lv1","lv97979", (byte) 1,new Date()));
list.add(new User(2,"lv2","lv97979", (byte) 1,new Date()));
list.add(new User(3,"lv3","lv97979", (byte) 1,new Date()));
list.add(new User(4,"lv4","lv97979", (byte) 1,new Date()));
//此写法直接返回int类型的值的集合
IntStream intStream = list.stream().mapToInt(User::getCustomerId);
intStream.forEach(System.out::println);
//此写法返回比较的结果,因为compareTo方法比较后返回的是0或1或-1都是int类型
IntStream intStream = list.stream().mapToInt(user -> user.getCustomerId().compareTo(2));
intStream.forEach(System.out::println);
}
mapToLong方法
与mapToInt方法类似,只是返回的中间流对象是long类型的流。
mapToDouble方法
与mapToInt方法类似,只是返回的中间流对象是double类型的流。
flatMap方法
此方法需要传递一个中间流对象作为参数,作用是筛选出当前流中与参数的流中满足条件的元素
这样理解:两个集合,要在哪个集合中查找满足条件的元素,这个集合就写成参数集合,用来匹配条件的集合调用flatmap方法。
//stream接口中
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1,"lv1","lv97979", (byte) 1,new Date()));
list.add(new User(2,"lv2","lv97979", (byte) 1,new Date()));
list.add(new User(3,"lv3","lv97979", (byte) 1,new Date()));
list.add(new User(4,"lv4","lv97979", (byte) 1,new Date()));
List<User> list2 = new ArrayList<>();
list2.add(new User(5,"lv1","lv97979", (byte) 1,new Date()));
list2.add(new User(6,"lv6","lv97979", (byte) 1,new Date()));
list2.add(new User(7,"lv7","lv97979", (byte) 1,new Date()));
List<Object> collect = list.stream().flatMap(user -> list2.stream().filter(l -> l.getLoginName().equals(user.getLoginName()))).collect(Collectors.toList());
System.out.println(collect);
}
结果:
[User(customerId=5, loginName=lv1, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 14:47:29 CST 2021)]
flatMapToInt方法
将作为参数的intStream流中的字符串元素解析为int类型元素。
这样理解:flatmap方法是查找参数流中满足条件的元素,flatmapToInt就是转换参数intStream流中的字符串元素转换为int类型元素。
//stream流接口中
IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1,"lv1","lv97979", (byte) 1,new Date()));
list.add(new User(2,"lv2","lv97979", (byte) 1,new Date()));
list.add(new User(3,"lv3","lv97979", (byte) 1,new Date()));
list.add(new User(4,"lv4","lv97979", (byte) 1,new Date()));
IntStream intStream = list.stream().flatMapToInt(user -> IntStream.of(user.getCustomerId()));
intStream.forEach(System.out::println);
}
结果:
1
2
3
4
flatMapToLong和flatMapToDouble方法
与上述flatMapToInt方法用法类似,返回的流类型不同。
distinct方法
去重,这个方法很好理解,就是去除集合中的重复元素,如下代码:
如果元素是对象,那该方法会比较对象中的所有属性值,判断是否相同,只要有一个不同都不是重复元素。
//stream流接口中
Stream<T> distinct();
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1,"lv1","lv97979", (byte) 1,new Date()));
list.add(new User(3,"lv3","lv97979", (byte) 1,new Date()));
list.add(new User(2,"lv2","lv97979", (byte) 1,new Date()));
list.add(new User(4,"lv4","lv97979", (byte) 1,new Date()));
list.add(new User(4,"lv4","lv97979", (byte) 1,new Date()));
List<User> collect1 = list.stream().distinct().collect(Collectors.toList());
collect1.forEach(System.out::println);
List<Integer> ints = new ArrayList<>();
ints.add(1);
ints.add(2);
ints.add(3);
ints.add(3);
ints.add(4);
ints.add(5);
List<Integer> collect = ints.stream().distinct().collect(Collectors.toList());
collect.forEach(System.out::println);
}
结果:
User(customerId=1, loginName=lv1, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 15:31:33 CST 2021)
User(customerId=3, loginName=lv3, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 15:31:33 CST 2021)
User(customerId=2, loginName=lv2, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 15:31:33 CST 2021)
User(customerId=4, loginName=lv4, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 15:31:33 CST 2021)
1
2
3
4
5
sorte方法
对数组的元素进行自然排序
注意:此方法对基本数据类型进行排序不需要传递比较器作为参数,对引用数据类型进行比较需要传递比较器,否则会报cannot be cast to java.lang.Comparable异常
//stream流中
Stream<T> sorted();
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1,"lv1","lv97979", (byte) 1,new Date()));
list.add(new User(3,"lv3","lv97979", (byte) 1,new Date()));
list.add(new User(2,"lv2","lv97979", (byte) 1,new Date()));
list.add(new User(5,"lv5","lv97979", (byte) 1,new Date()));
list.add(new User(4,"lv4","lv97979", (byte) 1,new Date()));
List<User> collect1 = list.stream().sorted(Comparator.comparing(User::getCustomerId)).collect(Collectors.toList());
collect1.forEach(System.out::println);
List<Integer> ints = new ArrayList<>();
ints.add(1);
ints.add(4);
ints.add(2);
ints.add(3);
ints.add(5);
List<Integer> collect = ints.stream().sorted().collect(Collectors.toList());
collect.forEach(System.out::println);
}
结果:
User(customerId=1, loginName=lv1, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 15:44:55 CST 2021)
User(customerId=2, loginName=lv2, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 15:44:55 CST 2021)
User(customerId=3, loginName=lv3, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 15:44:55 CST 2021)
User(customerId=4, loginName=lv4, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 15:44:55 CST 2021)
User(customerId=5, loginName=lv5, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 15:44:55 CST 2021)
1
2
3
4
5
peek方法
peek主要被用在debug用途。
注意:只写peek方法是没有任何输出值的,需要搭配其他方法调用,进行节点调试用。
//stream流中
Stream<T> peek(Consumer<? super T> action);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
List<User> collect1 = list.stream().sorted(Comparator.comparing(User::getCustomerId)).peek(e -> System.out.println("-------" + e)).collect(Collectors.toList());
}
结果:排序完成调试一次。
-------User(customerId=1, loginName=lv1, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:02:36 CST 2021)
-------User(customerId=2, loginName=lv2, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:02:36 CST 2021)
-------User(customerId=3, loginName=lv3, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:02:36 CST 2021)
-------User(customerId=4, loginName=lv4, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:02:36 CST 2021)
-------User(customerId=5, loginName=lv5, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:02:36 CST 2021)
limit方法
返回一个限制长度的stream流。
这样理解:其实就是将流截断,只取流的前n的元素组成一个集合。
//stream流中
Stream<T> limit(long maxSize);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
List<User> collect1 = list.stream().sorted(Comparator.comparing(User::getCustomerId)).limit(3).collect(Collectors.toList());
collect1.forEach(System.out::println);
}
结果:
User(customerId=1, loginName=lv1, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:07:08 CST 2021)
User(customerId=2, loginName=lv2, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:07:08 CST 2021)
User(customerId=3, loginName=lv3, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:07:08 CST 2021)
skip方法
丢弃从第一个元素开始的n个元素,将其余元素组成流返回。
//stream流中
Stream<T> skip(long n);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
List<User> collect1 = list.stream().sorted(Comparator.comparing(User::getCustomerId)).skip(3).collect(Collectors.toList());
collect1.forEach(System.out::println);
}
结果:
User(customerId=4, loginName=lv4, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:10:23 CST 2021)
User(customerId=5, loginName=lv5, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 16:10:23 CST 2021)
以上所有方法为中间方法,下面是终端方法(结束方法)。---------------------------------------------------------------------------------------++++++++++
forEach方法
遍历方法,和普通的forEach一样,不过括号中需要使用lambda表达式。
forEachOrdered方法
也是遍历方法,不过该方法只有并行流可以使用。串行流不能使用。
//stream流中
void forEachOrdered(Consumer<? super T> action);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
List<User> collect = list.stream().sorted(Comparator.comparing(User::getCustomerId)).collect(Collectors.toList());
collect.parallelStream().forEachOrdered(System.out::println);
}
toArray方法
将流转换为数组。
//stream流中
Object[] toArray();
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
Object[] collect = list.stream().sorted(Comparator.comparing(User::getCustomerId)).toArray();
}
reduce方法
累加方法,有三个重构方法:
三个方法的返回值不同,但累加的操作是相同的。
Optional<T> reduce(BinaryOperator<T> accumulator);
T reduce(T identity, BinaryOperator<T> accumulator);
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);
//用法
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
Integer reduce = list.stream().map(User::getCustomerId).reduce(100,(acc, item) -> {
System.out.println("acc : " + acc);
acc += item;
System.out.println("item: " + item);
System.out.println("acc+ : " + acc);
System.out.println("--------");
return acc;
});
System.out.println(reduce);
}
结果:
115
collect方法
将流转换为集合返回,需要传入一个Collector实现类
<R, A> R collect(Collector<? super T, A, R> collector);
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
List<User> collect = list.stream().filter(user -> user.getCustomerId() == 1).collect(Collectors.toList());
System.out.println(collect);
}
结果:
[User(customerId=1, loginName=lv1, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 17:37:07 CST 2021)]
min方法
返回流中最小的元素,需要传一个比较器作为参数。
Optional<T> min(Comparator<? super T> comparator);
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
Optional<User> min = list.stream().min(Comparator.comparing(User::getCustomerId));
System.out.println(min);
}
结果:
Optional[User(customerId=1, loginName=lv1, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 17:39:46 CST 2021)]
max方法
返回流中最大的元素,需要传一个比较器作为参数。与min用法一样。
Optional<T> max(Comparator<? super T> comparator);
count方法
返回元素个数合计
long count();
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
long count = list.stream().count();
System.out.println(count);
}
结果:
5
anyMatch方法
返回是否存在任一满足条件的元素。
boolean anyMatch(Predicate<? super T> predicate);
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
boolean lv3 = list.stream().anyMatch(user -> user.getLoginName().equals("lv3"));
System.out.println(lv3);
}
结果:
true
allMatch方法
返回所有元素是否满足条件。
boolean allMatch(Predicate<? super T> predicate);
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
boolean lv3 = list.stream().allMatch(user -> user.getPassword().equals("lv97979"));
System.out.println(lv3);
}
结果:
true
noneMatch方法
返回是否所有元素都不满足条件。
boolean noneMatch(Predicate<? super T> predicate);
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
boolean lv3 = list.stream().noneMatch(user -> user.getPassword().equals("lv921564"));
System.out.println(lv3);
}
结果:
true
findFirst方法
查找第一个元素
Optional<T> findFirst();
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
Optional<User> first = list.stream().findFirst();
System.out.println(first);
}
结果:
Optional[User(customerId=3, loginName=lv3, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 17:57:12 CST 2021)]
findAny方法
查找任意一个元素
Optional<T> findAny();
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(3, "lv3", "lv97979", (byte) 1, new Date()));
list.add(new User(1, "lv1", "lv97979", (byte) 1, new Date()));
list.add(new User(5, "lv5", "lv97979", (byte) 1, new Date()));
list.add(new User(2, "lv2", "lv97979", (byte) 1, new Date()));
list.add(new User(4, "lv4", "lv97979", (byte) 1, new Date()));
Optional<User> first = list.stream().findAny();
System.out.println(first);
}
结果:
Optional[User(customerId=3, loginName=lv3, password=lv97979, userStats=1, modifiedTime=Mon Jul 19 18:03:46 CST 2021)]
以上是终端方法,下面的方法是静态方法。----------------------------------------------------------------------+++++++++++++++++++++++++++++++
builder方法
builder方法是用来创建流接口的方法,如下面的方法,可以构建多个名字不同的流接口,再调用build进行实例化。
public static<T> Builder<T> builder() {
return new Streams.StreamBuilderImpl<>();
}
public static void main(String[] args) {
Stream.Builder<String> builder = Stream.builder();
builder.add("Production");
builder.add("Marketing");
builder.add("Finance");
builder.add("Sales");
builder.add("Operations");
Stream<String> stream = builder.build();
stream.forEach(System.out::println);
}
empty方法
用于构建一个空流对象,在使用流参数调用方法时,空流可能有助于避免 NullPointerException。
public static void main(String[] args) {
Stream<String> stream = Stream.empty();
stream.forEach(System.out::println);
}
of方法
of有两个方法,参数列表不同,一个为返回一个元素的流,另一个为返回包含给定元素的流。括号中可为空元素。
public static void main(String[] args) {
Stream<String> stream = Stream.of();
stream.forEach(System.out::println);
}
iterate方法
迭代方法,给定一个初始参数seed,再给定一个迭代条件,使seed按照条件进行迭代。
public static void main(String[] args) {
Stream.iterate(0, n -> n + 10).limit(3).forEach(System.out::println);
}
generate方法
返回一个无限连续的无序流,其中每个元素由提供的供应型(无参数有返回值)参数。如下所示:传递一个Random对象,作为参数
public static void main(String[] args) {
Stream.generate(() -> new Random().nextInt(10)).limit(5).forEach(System.out::println);
}
concat方法
用于合并流,将多个流合并为一个流,如下:前两个流对象中分别调用of创建了三个流,后调用concat方法进行合并。
public static void main(String[] args) {
String[] strings = {"meiyangyang","xiyangang","lanyangyang"};
Integer[] integers = {1,2,3};
Stream stream = Stream.of(strings);
Stream stream1 = Stream.of(integers);
Stream stream2 = Stream.concat(stream,stream1);
stream2.forEach(System.out::println);
}
三、optional类
optional类是一个容器类,保存类型为T的类,凡是对T类型的类的操作,都可以转化为对optional类的操作,优点在于能够避免空指针异常。
到此,jdk1.8新特性就差不多了。