java 8 stream流
什么是stream流
Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
Stream :非常方便精简的形式遍历集合实现 过滤、排序等。
Mysql:select userName from zhaoli where userName =‘zhaoli’
Order by age limt(0,2)
1.Stream创建方式
parallelStream
为并行流采用多线程执行
Stream
采用单线程执行
parallelStream
效率比Stream
要高。
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("zhaoli", 1));
userEntities.add(new UserEntity("fanjing", 5));
userEntities.add(new UserEntity("zhangshan", 4));
userEntities.add(new UserEntity("lisi", 3));
/**
* 创建 stream 流的俩种方式
* 1.串行流 stream()单线程
* 2.并行流 parallelStream()多线程
* 并行流比串行流效率要高
*/
userEntities.stream();
userEntities.parallelStream();
在Java中,可以通过以下方式来创建Stream流:
1. 通过集合创建流
集合类如List、Set等提供了stream()
方法,可以创建对应集合的流。
List<String> list = Arrays.asList("A", "B", "C");
Stream<String> stream = list.stream();
2. 通过数组创建流
数组通过静态方法Stream.of()
创建流。
String[] array = {"A", "B", "C"};
Stream<String> stream = Stream.of(array);
3. 通过Stream的静态方法创建流
Stream类提供了一些静态方法来创建流。
Stream<Integer> stream1 = Stream.empty(); // 创建一个空的流
Stream<Integer> stream2 = Stream.of(1, 2, 3); // 创建一个包含指定元素的流
// 创建一个无限流,从0开始每次增加2
Stream<Integer> stream3 = Stream.iterate(0, n -> n + 2);
// 创建一个无限流,随机生成100以内的整数
Stream<Integer> stream4 =
Stream.generate(() -> ThreadLocalRandom.current().nextInt(100));
4. 通过文件创建流
Files类提供了lines()
方法来创建从文件中读取的流。
Stream<String> stream = Files.lines(Paths.get("path/to/file.txt"));
5. 使用其他流的方法转换为新的流
Stream流提供了一些方法来对现有流进行转换、过滤、映射等操作。
Stream<String> stream1 = Stream.of("A", "B", "C");
Stream<String> stream2 = stream1.filter(s -> s.startsWith("A")); // 过滤以"A"开头的元素
Stream<Integer> stream3 = stream2.map(String::length); // 将元素映射为长度
这些是创建Stream流的一些常用方法,根据具体的需求选择适合的方式来创建流。
并行流与串行流区别
串行流:单线程的方式操作; 数据量比较少的时候。
并行流:多线程方式操作;数据量比较大的时候,原理:
Fork join 将一个大的任务拆分n多个小的子任务并行执行,
最后在统计结果,有可能会非常消耗cpu的资源,确实可以
提高效率。
注意:数据量比较少的情况下,不要使用并行流。
//串行流
Instant start = Instant.now();
long sum = 0;
for (long i = 0; i <= 10000000000L; i++) {
sum += i;
}
System.out.println(sum);
Instant end = Instant.now();
System.out.println("一百亿求和花费的时间为:"+ Duration.between(start,end).toMillis());
//并行流
Instant start = Instant.now();
LongStream longStream = LongStream.rangeClosed(0, 10000000000L);
OptionalLong result = longStream.parallel().reduce((l, r) -> l + r);
System.out.println(result.getAsLong());
Instant end = Instant.now();
//一百亿求和花费的时间为:1414
System.out.println("一百亿求和花费的时间为:"+ Duration.between(start,end).toMillis());
2.Stream将list转换为Set
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("赵立", 1));
userEntities.add(new UserEntity("小赵", 5));
UserEntity user = new UserEntity("张三", 4);
userEntities.add(user);
userEntities.add(user);
userEntities.add(new UserEntity("李四", 2));
System.out.println("去重前。。。");
userEntities.forEach((u) -> System.out.println(u));
System.out.println("去重后。。。");
/**
* 创建 stream 流的俩种方式
* 1.串行流 stream()单线程
* 2.并行流 parallelStream()多线程
* 并行流比串行流效率要高
*/
Stream<UserEntity> stream = userEntities.stream();
//转换为set集合
Set<UserEntity> userEntitySet = stream.collect(Collectors.toSet());
userEntitySet.forEach((t) -> System.out.println(t.toString()));
}
3.Stream将list转换为Map
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("赵立", 1));
userEntities.add(new UserEntity("小赵", 5));
userEntities.add(new UserEntity("李四", 2));
userEntities.add(new UserEntity("张三", 4));
//创建 stream 流
Stream<UserEntity> stream = userEntities.stream();
/**
* 转换为map集合
* list 集合只有元素值 key 要将其转化为map集合的情况下需要指定k-v 即key----user对象中的 userName 属性 value----为user对象
*
* (第一个 new Function<UserEntity, String>() UserEntity---list集合中的类型 String----指定key 的类型{return userEntity.getUserName()----给key赋值}
* 第二个 new Function<UserEntity, UserEntity>() UserEntity---list集合中的类型 UserEntity----指定value 的类型{return userEntity----给value赋值 })
*/
Map<String, UserEntity> UserEntitysMap = stream.collect(Collectors.toMap(new Function<UserEntity, String>() {
@Override
public String apply(UserEntity userEntity) {
return userEntity.getUserName();
}
}, new Function<UserEntity, UserEntity>() {
@Override
public UserEntity apply(UserEntity userEntity) {
return userEntity;
}
}));
UserEntitysMap.forEach(new BiConsumer<String, UserEntity>() {
@Override
public void accept(String s, UserEntity userEntity) {
System.out.println("key:"+s+",value:"+userEntity);
}
});
}
//精简写法
Map<String, UserEntity> UserEntitysMap = stream.collect
(Collectors.toMap(userEntity -> userEntity.getUserName(), userEntity -> userEntity));
UserEntitysMap.forEach((s, userEntity) ->
System.out.println("key:"+s+",value:"+userEntity));
4.Stream将Reduce 求和
Stream<Integer> integerStream = Stream.of(10, 50, 30, 10);
Optional<Integer> reduce = integerStream.reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer a1, Integer a2) {
return a1 + a2;
}
});
System.out.println(reduce.get());
//精简写法
Stream<Integer> integerStream = Stream.of(10, 50, 30, 10);
Optional<Integer> reduce = integerStream.reduce((a1, a2) -> a1 + a2);
System.out.println(reduce.get());
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("赵立", 1));
userEntities.add(new UserEntity("小赵", 5));
userEntities.add(new UserEntity("李四", 2));
userEntities.add(new UserEntity("张三", 4));
Stream<UserEntity> stream = userEntities.stream();
Optional<UserEntity> sumAge = stream.reduce(new BinaryOperator<UserEntity>() {
@Override
public UserEntity apply(UserEntity u1, UserEntity u2) {
UserEntity user = new UserEntity("sumAge", u1.getAge() + u2.getAge());
return user;
}
});
System.out.println(sumAge.get());
//精简写法
Optional<UserEntity> sumAge = stream.reduce((u1, u2) ->
new UserEntity("sumAge", u1.getAge() + u2.getAge()));
System.out.println(sumAge.get());
5.Stream查找Max和Min
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("赵立", 1));
userEntities.add(new UserEntity("小赵", 5));
userEntities.add(new UserEntity("李四", 2));
userEntities.add(new UserEntity("张三", 4));
Stream<UserEntity> stream = userEntities.stream();
//年龄最大的
Optional<UserEntity> max = stream.max(new Comparator<UserEntity>() {
@Override
public int compare(UserEntity o1, UserEntity o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println(max.get());
//年龄最小的
Optional<UserEntity> min = stream.min(new Comparator<UserEntity>() {
@Override
public int compare(UserEntity o1, UserEntity o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println(min.get());
//年龄最大的精简写法
Optional<UserEntity> max = stream.max((o1, o2) -> o1.getAge() - o2.getAge());
System.out.println(max.get());
//年龄最小的精简写法
Optional<UserEntity> min = stream.min((o1, o2) -> o1.getAge() - o2.getAge());
System.out.println(min.get());
6.StreamMatch 匹配
anyMatch表示,判断的条件里,任意一个元素成功,返回true
allMatch表示,判断条件里的元素,所有的都是,返回true
noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("赵立", 1));
userEntities.add(new UserEntity("小赵", 5));
userEntities.add(new UserEntity("李四", 2));
userEntities.add(new UserEntity("张三", 4));
Stream<UserEntity> stream = userEntities.stream();
//查找集合中是否存在姓名为小赵的 user
boolean result = stream.anyMatch(new Predicate<UserEntity>() {
@Override
public boolean test(UserEntity userEntity) {
return "小赵".equals(userEntity.getUserName());
}
});
System.out.println(result);
//精简写法
boolean result = stream.anyMatch((u)->"小赵".equals(u.getUserName()));
System.out.println(result);
7.StreamFor循环
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("赵立", 1));
userEntities.add(new UserEntity("小赵", 5));
userEntities.add(new UserEntity("李四", 2));
userEntities.add(new UserEntity("张三", 4));
Stream<UserEntity> stream = userEntities.stream();
stream.forEach((userEntity -> System.out.println(userEntity.toString())));
}
8.Stream过滤器
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("赵立", 18));
userEntities.add(new UserEntity("赵立", 16));
userEntities.add(new UserEntity("赵立", 20));
userEntities.add(new UserEntity("小赵", 19));
userEntities.add(new UserEntity("李四", 20));
userEntities.add(new UserEntity("张三", 17));
Stream<UserEntity> stream = userEntities.stream();
//找出所有姓名 赵立 年龄大于18岁的 user
stream.filter(new Predicate<UserEntity>() {
@Override
public boolean test(UserEntity userEntity) {
return "赵立".equals(userEntity.getUserName()) && userEntity.getAge() > 18;
}
}).forEach((u -> System.out.println(u.toString())));
//精简写法
stream.filter((u)-> "赵立".equals(u.getUserName()) && u.getAge() > 18)
.forEach((u -> System.out.println(u.toString())));
9.Stream排序 sorted
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("赵立", 1));
userEntities.add(new UserEntity("小赵", 5));
userEntities.add(new UserEntity("李四", 2));
userEntities.add(new UserEntity("张三", 4));
Stream<UserEntity> stream = userEntities.stream();
System.out.println("按照年龄升序");
stream.sorted(((o1, o2) -> o1.getAge()- o2.getAge()))
.forEach((u)-> System.out.println(u));
System.out.println("按照年龄降序");
stream.sorted(((o1, o2) -> o2.getAge()- o1.getAge())).forEach((u)-> System.out.println(u));
10.Stream limit和skip
Limit 从头开始获取
Skip 就是跳过
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("赵立", 1));
userEntities.add(new UserEntity("樊靖", 5));
userEntities.add(new UserEntity("李四", 2));
userEntities.add(new UserEntity("张三", 4));
userEntities.add(new UserEntity("王五", 3));
userEntities.add(new UserEntity("冯六", 6));
Stream<UserEntity> stream = userEntities.stream();
//取出前2个数据
stream.limit(2).forEach((u -> System.out.println(u)));
//先跳过2个数据再取出前3个数据
stream.skip(2).limit(3).forEach((u -> System.out.println(u)));
11.Stream 综合案例
public static void main(String[] args) {
ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("mayikt", 20));
userEntities.add(new UserEntity("mayikt", 21));
userEntities.add(new UserEntity("mayikt", 78));
userEntities.add(new UserEntity("mayikt", 32));
userEntities.add(new UserEntity("meite", 28));
userEntities.add(new UserEntity("zhangsan", 35));
userEntities.add(new UserEntity("xiaowei", 16));
userEntities.add(new UserEntity("mayikt_list", 109));
userEntities.add(new UserEntity("mayikt_zhangsan", 110));
userEntities.add(new UserEntity("lisi", 109));
//要求:对数据流的数据实现降序排列、且名称为mayikt 获取前两位
Stream<UserEntity> stream = userEntities.stream();
stream.sorted((o1, o2) -> o2.getAge() - o1.getAge())
.filter((u)->"mayikt".equals(u.getUserName()))
.limit(2)
.forEach((u) -> System.out.println(u));
}
JDK8 Optional
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()
方法会返回true,调用get()
方法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。
1.判断参数是否为空
ofNullable(可以传递一个空对象)
Of(不可以传递空对象)
Integer a1 = 1;
Optional<Integer> a = Optional.ofNullable(a1);
System.out.println(a.isPresent());
isPresent true 不为空 isPresent返回 false 为空。
参数为空可以设定默认值
Integer a1 = 5;
// Optional<Integer> a = Optional.ofNullable(a1);
// System.out.println(a.get());
// System.out.println(a.isPresent());
Integer a = Optional.ofNullable(a1).orElse(10);
System.out.println(a);
参数实现过滤
Integer a1 = 16;
Optional<Integer> a = Optional.ofNullable(a1);
boolean isPresent = a.filter(a2 -> a2 > 17).isPresent();
System.out.println(isPresent);
2.与Lambda表达式结合使用,优化代码
优化方案1
// 优化前
String mayiktName = "meite";
if (mayiktName != null) {
System.out.println(mayiktName);
}
//优化后
Optional<String> mayiktName2 = Optional.ofNullable(mayiktName);
// // 当value 不为空时,则不会调用
// mayiktName2.ifPresent(s -> System.out.println(s));
mayiktName2.ifPresent(System.out::print);
优化方案2
private static OrderEntity order = null;
public static void main(String[] args) {
OrderEntity order = Test06.getOrder();
System.out.println(order);
}
public static OrderEntity getOrder() {
// // 优化前
// if (order == null) {
// return createOrder();
// }
// return order;
/**
* orElseGet() ----写函数接口的形式 回赋值给成员属性 赋的是默认值
* orElse()---直接传递默认值 不进行赋值操作
*/
// 优化后
// return Optional.ofNullable(order).orElseGet(new Supplier<OrderEntity>() {
// @Override
// public OrderEntity get() {
// return createOrder();
// }
// });
return Optional.ofNullable(order).orElseGet(() -> createOrder());
}
private static OrderEntity createOrder() {
return new OrderEntity("123456", "mayikt");
}
优化方案3
map中获取的返回值自动被Optional包装,即返回值 -> Optional<返回值>
flatMap中返回值保持不变,但必须是Optional类型,即Optional<返回值> -> Optional<返回值>
public class Test07 {
public static void main(String[] args) {
String orderName = Test07.getOrderName();
System.out.println(orderName);
}
public static String getOrderName() {
// 优化前写法:
OrderEntity order = new OrderEntity("123456", "MAyikt");
if (order != null) {
String orderName = order.getOrderName();
if (orderName != null) {
return orderName.toLowerCase();
}
}
// return null;
//优化后写法:
return Optional.ofNullable(order)
.map(orderEntity -> orderEntity.getOrderName())
.map(name -> name.toLowerCase()).orElse(null);
}
}
相关文章:
《Java 8 新特性:Lambda 表达式与 Stream 流,重构你的编码效率(上篇:Lambda 表达式)》