stream流使用filter可以做到过滤筛选作用,本测试基于现有的筛选功能做了点修改,根据传入的参数可以实现动态的过滤筛选。传入的查询参数对象和集合里的对象可以不一样,但字段需要一致。
主要步骤:
1.利用反射获取查询参数queryParam对象的说所有方法
2.遍历反射获取到的所有方法,如果传入了参数,通过get方法可以获取到一个非空的值(查询参数对象queryParam里面的基本数据类型都需要转换为对应的封装类型,如int -> Integer,否则会有默认值为0,不好判断该值是否传入的值)
3.通过Method的invoke执行对象的目标方法获取传入查询参数的值
4.在stream().filter方法里面遍历每一条记录时,再调用Method的invoke方法获取每一条记录对应的值,然后比对外面获取到查询参数的对象与该对象是否相等
具体实现:
接口创建了4个Person对象
@RequestMapping(value = "/auth/test/selectTest",method = {RequestMethod.GET, RequestMethod.POST})
public Object selectTest(Person queryParam){
List list = new ArrayList<>();
Person person1 = new Person(1L,"路飞",20);
Person person2 = new Person(2L,"路飞",21);
Person person3 = new Person(3L,"索隆",20);
Person person4 = new Person(4L,"娜美",20);
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
long startTime = System.currentTimeMillis();
try{
list = screen(list,queryParam);
}catch (Exception e){
logger.info("处理异常");
}
long endTime = System.currentTimeMillis();
Object obj= JSONObject.toJSON(list);
logger.info("所需时间:{}",endTime-startTime);
return obj;
}
/**
* @param list 需要筛选的集合
* @param queryParam 筛选参数
* @return
*/
public List screen(List list,Person queryParam) throws Exception {
Method[] methods = queryParam.getClass().getMethods();
for (int i = 0; i < methods.length; i++) {
String get = methods[i].getName();
/**传入的参数可以通过get方法获取,过滤掉非get方法*/
if(!get.startsWith("get")){
continue;
}
Object obj2 = queryParam.getClass().getMethod(get).invoke(queryParam);
/**过滤掉没有传入的查询参数*/
if(ObjectUtil.isNull(obj2)){
continue;
}
list = list.stream().filter(item -> {
boolean check = false;
try {
Object obj1 = item.getClass().getMethod(get).invoke(item);
/**查看返回的对象是否同一个*/
check = ObjectUtil.equal(obj1,obj2);
} catch (Exception e) {
e.printStackTrace();
}
return check;
}).collect(Collectors.toList());
}
return list;
}
Person对象
package com.example.demo.entity;
import java.io.Serializable;
/**
* @author 小豆芽
* @version 1.0
* @Date 2020-12-09 10:11
*/
public class Person implements Serializable {
private Long id;
private String name;
private Integer age;
public Person() {}
public Person(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
测试结果,传入name筛选出路飞
传入name和age,筛选出21岁的路飞
上面的例子可以筛选了,接下来对接口数据做一下修改,测试耗时,创建20万条数据
@RequestMapping(value = "/auth/test/selectTest",method = {RequestMethod.GET, RequestMethod.POST})
public Object selectTest(Person queryParam){
List list = new ArrayList<>();
Person person1 = new Person(1L,"路飞",20);
Person person2 = new Person(2L,"路飞",21);
Person person3 = new Person(3L,"索隆",20);
Person person4 = new Person(4L,"娜美",20);
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
/**创建20万条数据*/
for (int i = 5; i < 200000; i++) {
Person person = new Person((long) i,"路飞",20);
list.add(person);
}
long startTime = System.currentTimeMillis();
try{
list = screen(list,queryParam);
}catch (Exception e){
logger.info("处理异常");
}
long endTime = System.currentTimeMillis();
Object obj= JSONObject.toJSON(list);
logger.info("所需时间:{}",endTime-startTime);
return obj;
}
测试结果,20万条数据处理结果大概250毫秒左右
测试200万条数据时需要2.5秒左右,当然如果数据量太大的话内存也是会溢出的。
本测试用例只能做一个简单的动态筛选,还有很多场景还没考虑到,这里只做一个参考