在日常开发的过程中我们经常会遇到需要 mock 一些数据的场景,比如说 mock 一些接口的返回或者说 mock 一些测试消息用于队列生产者发送消息,可能很多时候我们都是使用一些固定的 case 或者一条相同的数据重复使用 。今天阿粉就教大家用 Stream 去构造一些伪真实的一些数据 。
Mock 任意个 UUID首先我们通过普通写法来构造 100 个 UUID,代码如下相信大家都会写,就不多说了 。
public static List<UUID> listUUID(int size) {List<UUID> list = new ArrayList<>();for (int i = 0; i < size; i++) {UUID uuid = UUID.randomUUID();list.add(uuid);}return list;}
下面再提供 Stream 的写法,代码如下,一行搞定
public static List<UUID> listUUID2(int size) {return Stream.generate(UUID::randomUUID).limit(size).collect(Collectors.toList());}
这里我们使用了 Stream 的 generate 方法,该方法接收一个 Supplier 类型的参数,Supplier 是一个功能接口,只有一个 get 方法,返回一个对象,不接收任何参数,上面我们就是通过 UUID 静态引用的方式获得一个 UUID 对象,另外我们使用 limit 方法来进行截断只获取 100 个 。
Mock 消息接下来我们再使用 Stream API 批量构造一批消息,作为队列的生产者进行数据发送
定义消息体
package com.example.demo.dto;/** * <br> * <b>Function:</b><br> * <b>Author:</b>@author JAVA 极客技术<br> * <b>Date:</b>2022-09-03 11:49<br> * <b>Desc:</b>无<br> */public class Message {int id;String message;public Message(int id, String message) {this.id = id;this.message = message;}@Overridepublic String toString() {return "Message{" +"id=" + id +", message='" + message + ''' +'}';}}
测试代码
public static void main(String[] args) {List<Message> messages = genMessage(10);messages.forEach(System.out::println);}public static List<Message> genMessage(int size) {AtomicInteger atomicInteger = new AtomicInteger();Supplier<Message> supplier = () -> {Message message = new Message(new Random().nextInt(), "Message : " + atomicInteger.getAndIncrement());System.out.println("inner:" + message.toString());return message;};System.out.println(99);return Stream.generate(supplier).limit(size).collect(Collectors.toList());}
文章插图
先看下运行结果,我们再来分析,可以看到第一个 case 我们是使用静态引用来返回一个 UUID 对象,这个 case 我们通过创建 lambda 表达式的形式来实现一个 Supplier,在表达式中我们进行 message 对象的构造,然后进行返回 。其实上文的静态引用,本质上也是一个 lambda,所以跟下面的实现是一个原理,只不过是一些语法糖而已 。
public static List<UUID> listUUID2(int size) {Supplier<UUID> supplier = () -> UUID.randomUUID();return Stream.generate(supplier).limit(size).collect(Collectors.toList());}
如果对 Stream 流有理解的可以看到,我们这里有两个点需要注意,一个是我们这里的输出 99 是在 inner 之前的,另一个是我们这里使用的 limit 方法,不然会一直进行输出不会停止的,这两点其实都是流的基本特性,就不多说了 。Supplier 是个啥上文提到 Stream 的 generate 方法接收的是一个 Supplier 类型的参数,那么这个 Supplier 是个啥呢?我们来仔细看一下 。
package java.util.function;@FunctionalInterfacepublic interface Supplier<T> {/*** Gets a result.** @return a result*/T get();}
通过代码我们可以看到首先 Supplier 是个接口,既然是接口那就可以进行具体的实现,并且这个接口只有一个方法 get 返回指定的类型,同时该接口还有一个 @FunctionalInterface 注解,表明这个接口是一个函数是编程的接口,函数式接口是指仅仅只包含一个抽象方法的接口 。文章插图
我们看到这个注解的 javadoc 里面大概的意思是这个注解是用来标识一个函数接口,函数式接口只有一个抽象方法,但是如果有 default 方法或者覆盖了 Object 的 public 方法都不算是抽象方法 。还有一句讲的是函数式接口可以通过 lambda 表达式,方法引用或者构造方法引用来创建 。我们上面的两个例子演示了 lambda 表达式和方法引用,构造函数其实也一样 。
推荐阅读
- 你真的了解无线网络覆盖范围吗?
- 阿里开源的一个插件化前端框架,腾讯、美团、字节都在用
- 面试官:有一个 List 对象集合,如何优雅地返回给前端?我懵了
- AutoGadgetFS:一款针对USB设备的安全测试工具
- 经典SQL语句大全
- minio集群将一切访问都交给nginx
- springboot 缓存一致性常用解决方案
- 软件测试中的设计思维
- 数据仓库、数据湖、湖仓一体,究竟有什么区别?
- |和田玉一路莲科把件