JAVA8新特性(下篇)

四. Stream

1. 描述

流模式: 对流元素按队列(顺序)进行聚合操作
串行: 以单一数据块执行
并行: 切分为多数据块执行
通常是为了简化集合和数组的遍历操作

2. 格式

聚合函数连续调用

3. 特征

元素队列元素 是特定类型的对象, 形成一个队列。 Java中的Stream并不会存储元素, 也不会改变原对象, 而是按需计算。
数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
聚合操作 处理结果是新的Stream流, 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
终止操作 结果不再是流,而是流元素的实例或者操作结果, 比如:forEache, count, collect
和以前的Collection操作不同, Stream操作还有两个基础的特征:
Pipelining: 中间操作都会返回新的流对象。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。
内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
注意:

  1. Stream流是延迟执行的, 只有在执行结束操作(有结果时)时,才会执行之前的Stream操作
    以下Stream流中调用了map聚合函数, 并在该聚合函数中添加了打印信息
    但控制台并未输出相关内容
    调用终止函数后, 打印了内容数据
private static void streamStart() {
    List<Box> boxes = GenerateUtil.generateBoxes();
    System.out.println("测试流过程开始");
    Stream<String> stringStream = boxes.stream()
            .map(box -> {
                System.out.println("box: " + box);
                return box.getColor();
            });
    System.out.println("流过程初始化完成");
    // 遇到count时执行stream流
    long count = stringStream.count();
    System.out.println("测试流过程结束");
}

流程测试结果

  1. 调用聚合函数后返回的是新的Stream
private static void otherStream() {
    List<Box> boxes = GenerateUtil.generateBoxes();
    System.out.println("测试流过程开始");
    Stream<Box> stream1 = boxes.stream();
    System.out.println(stream1);
    Stream<Box> stream2 = stream1.filter(box -> box.getSize() >= 3);
    System.out.println(stream2);
    Stream<String> stream3 = stream2.map(Box::getColor);
    System.out.println(stream3);
    System.out.println("测试流过程结束");
}

聚合函数结果

4. 案例
  1. 获取流的方法
    Stream.of()Collection.stream()
private static void streamOf() {
    Stream<String> stringStream = Stream.of("a", "b", "c");
    String[] a = {"a", "b", "c"};
    Stream.of(a).forEach(System.out::println);
	List<Box> boxes = GenerateUtil.generateBoxes();
    Stream<Box> stream1 = boxes.stream();
}
  1. forEach方法
    参考上述内容
    终止函数
    对流元素进行遍历操作, 返回值为void
  2. count方法
    终止函数
    对当前Stream流中的流元素进行计数并返回为long
private static void count() {
    List<Box> boxes = GenerateUtil.generateBoxes();
    long count = boxes.stream().count();
    System.out.println("初始size:" + count);
    long count1 = boxes.stream().filter(box -> box.getSize() >= 3).count();
    System.out.println("过滤后size:" + count1);
}

count执行结果
4. reduce方法
终止函数
将当前Stream流中的流元素进行归约操作, 上一次操作的结果作为这一次操作的一个 参数

private static void reduce() {
    Integer[] numbers = {2, 1, 1, 4, 1, 6, 2};
    List<Integer> num = new ArrayList<>(Arrays.asList(numbers));
    Integer reduce = num.stream()
            .reduce(0, (result, item) -> result += item);
    System.out.println(reduce);
}

ewsuce结果
第一: 操作项不限于数值
第二: 处理操作不限于sum,max等数值计算, 也可以用作字符串拼接等
第三: result参数类型与处理操作返回值的类型相同, item参数类型与当前Stream流中的 泛型类型相同
5. find方法
终止函数
查找元素
findFirst->查找第一个元素
findAny->查找任意一个元素(串行Stream流也是查找第一个元素)

private static void find() {
    OptionalInt any = IntStream.range(0, 100000).parallel().findAny();
    any.ifPresent(System.out::println);
}

find方法结果
6. match 方法
终止函数
流元素匹配内容的结果
allMatch -> 全元素匹配
anyMatch -> 有匹配元素
noneMatch -> 没有匹配元素

private static void match() {
    String[] strings = {"auyj", "byjk", "cyp89i", "dyuj"};
    boolean a = Stream.of(strings).anyMatch(item -> item.startsWith("a"));
    System.out.println(a);
}
  1. collect方法
    终止函数
    Stream流转换为其他形式
private static void count() {
    List<Box> boxes = GenerateUtil.generateBoxes();
    Set<Box> boxes2 = boxes.stream().collect(Collector::toSet);
}
  1. filter方法
    聚合函数
    对当前Stream流中的流元素进行筛选操作, 返回新的Stream
private static void filter() {
    Integer[] numbers = {1, 2, 3, 4, 5, 6, 7};
    Stream<Integer> stream1 = Stream.of(numbers);
    System.out.println("过滤前内容:");
    stream1.forEach(System.out::println);
    System.out.println("过滤后内容:");
    Stream<Integer> stream2 = Stream.of(numbers);
    stream2.filter(box -> box > 3).forEach(System.out::println);
}

filter方法结果
9. map方法
聚合函数
对当前Stream中的流元素进行处理, 并返回新的映射元素的Stream

private static void map() {
    List<Box> boxes = GenerateUtil.generateBoxes();
    boxes.stream()
            .map(Box::getColor)             //处理操作
            .forEach(System.out::println);  //遍历输出
}

map方法结果
10. distinct方法
聚合函数
对当前Stream流中的流元素进行去重,使用equals方法和hashCode方法判断(基本类型 使用”==”)是否相等

private static void distinct() {
    Integer[] numbers = {1, 2, 1, 4, 1, 6, 2};
    Stream.of(numbers).distinct().forEach(System.out::println);
}

distinct方法结果
11. sorted方法
聚合函数
Stream流中的流元素进行规则排序

private static void sort() {
    Integer[] numbers = {2, 1, 1, 4, 1, 6, 2};
    List<Integer> num = new ArrayList<>(Arrays.asList(numbers));
    List<Integer> collect = num.stream()
            .sorted()
            .collect(Collectors.toList());
    System.out.println(collect);
}

sorted方法结果
12. skip方法
聚合函数
从当前Stream流中跳过前n条数据(舍弃前n条数据)

private static void skip() {
    Integer[] numbers = {2, 1, 1, 4, 1, 6, 2};
    List<Integer> num = new ArrayList<>(Arrays.asList(numbers));
    List<Integer> collect = num.stream()
            .skip(3)
            .collect(Collectors.toList());
    System.out.println(collect);
}

skip方法结果
13. limit方法
聚合函数
从当前Stream流中截取前n条数据()舍弃之后的数据)

private static void limit() {
    Integer[] numbers = {2, 1, 1, 4, 1, 6, 2};
    List<Integer> num = new ArrayList<>(Arrays.asList(numbers));
    List<Integer> collect = num.stream()
            .limit(3)
            .collect(Collectors.toList());
    System.out.println(collect);
}

limit方法结果
截取了前三条数据, 数值小于 0 ,会抛出IllegalArgumentException
14. concat方法
聚合函数
静态方法
对两个Stream流中的流元素进行合并, 获得合并后的元素Stream

private static void concat() {
    Integer[] numbers = {2, 1, 1, 4};
    List<Integer> num = new ArrayList<>(Arrays.asList(numbers));
    String[] strings = {"a", "b", "c", "d"};
    List<String> strs = new ArrayList<>(Arrays.asList(strings));
    List<? extends Serializable> collect = Stream.concat(num.stream(), strs.stream())
            .collect(Collectors.toList());
    System.out.println(collect);
}

concat方法结果
合并操作会操作泛型, 如果流元素的泛型类型相同则结果就是该泛型类型,如果不相同, 则会返回公共父类类型作为泛型

五. JAVA日期

1. 描述

LocalDate: 当地日期
LocalTime: 当地时间
LocalDateTime: 当地日期时间, 内部维护LocalDateLocalTime
ZonedDateTime: 带有时区的日期时间
Instante: 时间戳

2. 新特点
  1. 线程安全、不可修改
  2. 月份星期改为枚举
  3. 将日期和时间分开
  4. 简化了时区问题
3. 案例

注意: 为便于描述, 以下描述中的 ‘日期’ 均指代日期(LocalDate)与时间(LocalTime)

  1. 创建
    now: 创建 ‘日期’ 实例
    of: 创建目标 ‘日期’ 实例
    parse: 将目标字符解析为 ‘日期’ 实例
private static void create() {
    LocalTime localTime = LocalTime.now();
    System.out.println("时间: " + localTime);
    LocalDate localDate = LocalDate.of(2022, 1, 21);
    System.out.println("日期: " + localDate);
    LocalDateTime localDateTime = LocalDateTime.parse("2022-01-21 14:22:23", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    System.out.println("日期和时间: " + localDateTime);
}

创建时间方式结果
2. 获取相关内容
GetXxx:

private static void get() {
    LocalDateTime localDateTime = LocalDateTime.now();
    System.out.println("年: " + localDateTime.getYear());
    System.out.println("月: " + localDateTime.getMonth());
    System.out.println("日: " + localDateTime.getDayOfMonth());
    System.out.println("时: " + localDateTime.getHour());
    System.out.println("分: " + localDateTime.getMinute());
    System.out.println("秒: " + localDateTime.getSecond());
    System.out.println("纳秒: " + localDateTime.getNano());
}
  1. 提前或推迟或定位日期
    pinus/minusXxxx: 提前到新的 ‘日期’ , 返回新的 ‘日期’ 实例
    plus/plusXxxx: 推迟到新的 ‘日期’ , 返回新的 ‘日期’ 实例
    with/withXxxx: 定位到新的 ’日期’ , 返回新的 ‘日期’ 实例
private static void plusAndMinusAndWith() {
    LocalDateTime localDateTime = LocalDateTime.now();
    System.out.println("源数据: " + localDateTime);
    LocalDateTime plus = localDateTime.plus(100L, ChronoUnit.HOURS);
    System.out.println("加 100 小时: " + plus);
    LocalDateTime plusDays = localDateTime.plusDays(3L);
    System.out.println("加 3 天: " + plusDays);
    System.out.println("减 1 天: " + localDateTime.minus(1L, ChronoUnit.DAYS));
    System.out.println("定位到当月 1 日: " + localDateTime.with(ChronoField.DAY_OF_MONTH, 1));
}

时间提前或者推迟的结果
4. 格式化
format: 根据 ‘日期’ 格式器格式化 ‘日期’

private static void format() {
    LocalDateTime now = LocalDateTime.now();
    System.out.println("格式化后字符串: " + now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}

format方法结果

日 期 : 2022 − 02 − 12 \color{#00FF00}{日期:2022-02-12} 20220212

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值