java 集合反射_java List集合利用反射结合流的filter做一个筛选

本文介绍如何利用Java反射与Stream的filter方法,根据动态查询参数进行集合筛选。详细步骤包括:1) 通过反射获取查询参数对象的所有方法;2) 遍历并获取每个方法的非空值;3) 在Stream中比较每条记录与查询参数的值。文中还展示了Person对象的筛选示例,并测试了不同数据量下的筛选效率。
摘要由CSDN通过智能技术生成

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筛选出路飞

cfafcdd151af3a665744a3b6e842feb8.png

传入name和age,筛选出21岁的路飞

05e79c5081af4888f891237f77ba82db.png

上面的例子可以筛选了,接下来对接口数据做一下修改,测试耗时,创建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毫秒左右

d69f2127a707a7c391d381bb144a3cb8.png

测试200万条数据时需要2.5秒左右,当然如果数据量太大的话内存也是会溢出的。

本测试用例只能做一个简单的动态筛选,还有很多场景还没考虑到,这里只做一个参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值