IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Stream流式惰性计算 -> 正文阅读

[Java知识库]Stream流式惰性计算

1.生成斐波那契数列(Stream基本使用)

要求是编写一个能输出斐波拉契数列(Fibonacci)的LongStream

因为Java的范型不支持基本类型,所以我们无法用Stream<long>这样的类型,会发生编译错误。为了保存long,只能使用Stream<Long>,但这样会产生频繁的装箱、拆箱操作。

为了提高效率,Java标准库提供了IntStream、LongStream和DoubleStream这三种使用基本类型的Stream,它们的使用方法和范型Stream没有大的区别

public class Main {
	public static void main(String[] args) throws IOException {
		LongStream fib = LongStream.generate(new FibSupplier());
		// 打印Fibonacci数列:1,1,2,3,5,8,13,21...
		fib.limit(10).forEach(System.out::println);
	}
}

class FibSupplier implements LongSupplier {
    long first = 0;
    long second = 1;
    public long getAsLong() {
        long p = second;
        second += first;
        first = p;
        return first;
    }
}

2. String 转换为LocalDate (map使用)

正常转换:


import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
/**
 * 	String 类型转为 LocalDate类型
 *
 */
public class DemoDate {
	public static void main(String[] args) {
		String date1 = "2021-06-13";
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		LocalDate date2 = LocalDate.parse(date1, fmt);
		System.out.println(date1);
		System.out.println(date2);
	}
}

case1:不指明format

 String[] strs = new String[]{"2021-01-02", "2021-07-02"};
 Stream.of(strs).map(LocalDate::parse).forEach(System.out::println);

case2: 指明format:

匿名函数版本:
String[] strs = new String[]{"2021-01-02", "2021-07-02"};
Stream.of(strs).map(str -> {
     return LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}).forEach(System.out::println);

优化版本:     
String[] strs = new String[]{"2021-01-02", "2021-07-02"};
Stream.of(strs).map(str -> LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-MM-dd"))).forEach(System.out::println);

3.从一组给定的LocalDate中过滤掉工作日,得到休息日(filter 使用)

filter()除了常用于数值外,也可应用于任何Java对象。
例如,从一组给定的LocalDate中过滤掉工作日,以便得到休息日:

public class Main {
    public static void main(String[] args) {
        Stream.generate(new LocalDateSupplier())
                .limit(31) // 调用31次LocalDateSupplier.get方法,得到31个ldt
                .filter(ldt -> ldt.getDayOfWeek() == DayOfWeek.SATURDAY || ldt.getDayOfWeek() == DayOfWeek.SUNDAY) // 过滤掉工作日
                .forEach(System.out::println);
    }
}

class LocalDateSupplier implements Supplier<LocalDate> {
    LocalDate start = LocalDate.of(2021, 1, 1);// 起始日期2021.1.1
    int n = -1;
    public LocalDate get() {
        n++;
        return start.plusDays(n); // 起始日期+步进增量n
    }
}

3. reduce计算

4. 输出为集合或者数组

输出为List、Set:

一组String先过滤掉空字符串,然后把非空字符串保存到List中

public class Main {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("Apple", "", null, "Pear", "  ", "Orange");
        List<String> list = stream.filter(s -> s != null && !s.isBlank()).collect(Collectors.toList());
        System.out.println(list);
    }
}

把Stream的每个元素收集到List的方法是调用collect()并传入Collectors.toList()对象,它实际上是一个Collector实例,通过类似reduce()的操作,把每个元素添加到一个收集器中(实际上是ArrayList)。

类似的,collect(Collectors.toSet())可以把Stream的每个元素收集到Set中。

输出为数组

把Stream的元素输出为数组和输出为List类似,我们只需要调用toArray()方法,并传入数组的“构造方法”:

List<String> list = List.of("Apple", "Banana", "Orange");
String[] array = list.stream().toArray(String[]::new);

注意到传入的“构造方法”是String[]::new,它的签名实际上是IntFunction<String[]>定义的String[] apply(int),即传入int参数,获得String[]数组的返回值。

输出为map:

如果我们要把Stream的元素收集到Map中,就稍微麻烦一点。因为对于每个元素,添加到Map时需要key和value,因此,我们要指定两个映射函数,分别把元素映射为key和value:

public class Main {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("APPL:Apple", "MSFT:Microsoft");
        Map<String, String> map = stream
                .collect(Collectors.toMap(
                        // 把元素s映射为key:
                        s -> s.substring(0, s.indexOf(':')),
                        // 把元素s映射为value:
                        s -> s.substring(s.indexOf(':') + 1)));
        System.out.println(map);
    }
}

分组输出

public class Main {
    public static void main(String[] args) {
        List<String> list = List.of("Apple", "Banana", "Blackberry", "Coconut", "Avocado", "Cherry", "Apricots");
        Map<String, List<String>> groups = list.stream()
                .collect(Collectors.groupingBy(s -> s.substring(0, 1), Collectors.toList()));
        System.out.println(groups);
    }
}

分组输出使用Collectors.groupingBy(),它需要提供两个函数:
一个是分组的key,这里使用s -> s.substring(0, 1),表示只要首字母相同的String分到一组,
第二个是分组的value,这里直接使用Collectors.toList(),表示输出为List,上述代码运行结果如下:

{
    A=[Apple, Avocado, Apricots],
    B=[Banana, Blackberry],
    C=[Coconut, Cherry]
}

可见,结果一共有3组,按"A",“B”,"C"分组,每一组都是一个List。

Stream提供的常用操作:

转换操作:map()filter()sorted()distinct();

合并操作:concat()flatMap();

并行处理:parallel();

聚合操作:reduce()collect()count()max()min()sum()average();

其他操作:allMatch(), anyMatch(), forEach()
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 00:11:50  更:2021-07-28 00:12:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/1 21:03:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码