import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** List中根据对象字段快速查找对象* @date 2020-05-12 9:47*/
public class FSearchUtil {private StringBuffer mKeyWordString = new StringBuffer();private List<Object> mSearchObjs = new ArrayList<>();private int[] mIndexes;public FSearchUtil(List<? extends Object> objects, String... fields) throws Exception {super();init(objects, fields);}private void init(List<? extends Object> objs, String... fields) throws Exception {if (objs != null) {mKeyWordString.setLength(0);mSearchObjs.clear();mSearchObjs = new ArrayList<>(objs);mIndexes = new int[mSearchObjs.size() * 2];int index = 0;for (int i = 0; i < mSearchObjs.size(); i++) {Object info = mSearchObjs.get(i);// 指定要搜索的字段String searchKey = getSearchKey(info, fields);// 将该字符串在总字符串中的起终位置保存下来,位置是索引值而非长度int length = mKeyWordString.length();mIndexes[index] = length;mKeyWordString.append(searchKey);length = mKeyWordString.length();index++;// 保存新加搜索字段的索引值mIndexes[index] = (length > 0) ? length - 1 : 0;index++;}}}/*** 通过反射从对象中取出指定字段的值*/private String getSearchKey(Object obj, String... fields) throws Exception {StringBuilder searchKeys = new StringBuilder();Class<? extends Object> clazz = obj.getClass();try {for (String str : fields) {// 搜索字段使用空格隔开Field f = clazz.getDeclaredField(str);f.setAccessible(true);Object val = f.get(obj);searchKeys.append(val).append(" ");f.setAccessible(false);}} catch (Exception e) {throw new Exception("取值异常:" + e.getMessage());}return searchKeys.toString();}/*** 搜索结果** @param keyWords*            搜索的关键字,要去掉首尾的空格* @return 返回搜索到的对象*/public List<Object> searchTasks(String keyWords) {List<Object> searchedTask = new ArrayList<>();int[] searchIndex = getSearchIndex(keyWords);for (int index : searchIndex) {if (index != -1 && index < mSearchObjs.size() * 2) {Object info = mSearchObjs.get(index / 2);if (info != null && !searchedTask.contains(info)) {searchedTask.add(info);}}}return searchedTask;}/*** 找到匹配的索引数据** @param keyWords*            搜索的关键字* @return 在初始化的索引数组的下标数组*/private int[] getSearchIndex(String keyWords) {Pattern pattern = Pattern.compile(keyWords, Pattern.CASE_INSENSITIVE | Pattern.LITERAL);Matcher matcher = pattern.matcher(mKeyWordString.toString());ArrayList<Integer> searchResult = new ArrayList<>();while (matcher.find()) {// 不宜在此处再做循环,否则可能造成循环次数过多错误searchResult.add(matcher.start());}int[] searchIndexes = new int[searchResult.size()];for (int i = 0; i < searchIndexes.length; i++) {int findIndex = findIndex(searchResult.get(i));searchIndexes[i] = (findIndex / 2) * 2;}return searchIndexes;}/*** 使用二分法找到指定字符位置在索引数组中的位置** @param charAt*            字符在整个字符串中的位置* @return 在索引数组中的位置*/private int findIndex(int charAt) {int low = 0;int high = mIndexes.length - 1;int mid = -1;while (low <= high) {mid = (low + high) >>> 1;int midVal = mIndexes[mid];if (midVal < charAt) {low = mid + 1;} else if (midVal > charAt) {high = mid - 1;} else {return mid;}}return mid;}
// 使用样例
FSearchUtil tool = new FSearchUtil(outList, "userName", "deptName", "orgName");
tool.searchTasks(keyword);

List中根据对象字段快速查找对象相关推荐

  1. XGBoost中分位点算法快速查找分割点

    (作者:陈玓玏) 写在前面:这篇博客我自认为写得不太好,有些问题可能我自己也没有弄得多清楚,对文章有疑问的朋友可以留言讨论,不胜感激. 1.基本的查找分割点的贪婪算法 这样的算法称为精确贪婪算法,在计 ...

  2. Cadence OrCAD原理图中快速查找元件的方法

    Cadence OrCAD原理图中快速查找元件和网络方法 本章节将教大家如何在OrCAD原理图中根据元件位号快速查找元件的两个方法. 方法一:在.obj页面的"File"标签下查找 ...

  3. JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配

    文章目录 前言 零.排序规范 1.happens-before原则 2.找文档位置 一.一线互联网企业关于对象面试题: (后面回答的就是这几个问题) 二.对象创建过程 三.对象在内存中的存储布局 1. ...

  4. java 对象怎么序列化,java对象序列化总结

    java对象序列化小结 百度百科上介绍序列化是这样的: 序列化 (Serialization): 将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储 ...

  5. 对象实例数据和对象类型数据

    对象实例数据(堆):对象中各个实例字段的数据 对象类型数据(方法区):对象的类型.父类.实现的接口.方法等 静态区(也在方法区中)用来存放静态变量,静态块 ---------------------- ...

  6. 最长公共子序列_使用序列化查找对象中的脏字段

    最长公共子序列 假设您正在开发一个将对象自动保存到数据库中的框架. 您需要检测两次保存之间所做的更改,以便仅保存修改的字段. 如何检测脏场. 最简单的方法是遍历原始数据和当前数据,并分别比较每个字段. ...

  7. java对象序列化去掉字段_使用序列化查找对象中的脏字段

    java对象序列化去掉字段 假设您正在开发一个将对象自动保存到数据库中的框架. 您需要检测两次保存之间所做的更改,以便仅保存已修改的字段. 如何检测脏场. 最简单的方法是遍历原始数据和当前数据,并分别 ...

  8. 使用序列化查找对象中的脏字段

    假设您正在开发一个将对象自动保存到数据库中的框架. 您需要检测两次保存之间所做的更改,以便仅保存修改过的字段. 如何检测脏场. 最简单的方法是遍历原始数据和当前数据,并分别比较每个字段. 代码如下: ...

  9. 【Android NDK 开发】JNI 方法解析 ( C/C++ 设置 Java 对象字段 | 查找字段 | 设置字段 )

    文章目录 I . 设置 Java 对象 属性 流程 II . 查找 Java 对象属性 ( GetFieldID ) III . 设置 Java 对象属性 ( SetXxxField ) I . 设置 ...

最新文章

  1. Autodesk PowerInspect 2021中文版
  2. 输入法之核心词典构建
  3. 阿里云发布大数据产品ODPS 6小时处理100PB数据
  4. 移动表到另一表空间命令
  5. IS-IS详解(十)——IS-IS 骨干区域与非骨干区域访问进阶
  6. JSP实用教程(3)——JSP内置对象
  7. Matlab画图和点标记
  8. Lodash兼容IE6~IE8
  9. Idea 编译报错:Ambiguous method call. Both...
  10. js框架jquery实现的幸运大转盘抽奖程序代码,兼容多种浏览器(Internet Explorer 6.0+ 、Firefox 2.0 、Safari 3 、Opera 9 、Chrome)
  11. Android倒计时定时器CountDownTimer的用法
  12. WebRTC 的黎明
  13. 华为鸿蒙系统超级终端,华为再发新版鸿蒙OS系统!新增超级终端功能:可媲美iOS系统...
  14. PW4203降压型1-3节锂电池充电芯片
  15. 如果不使用时钟同步工具,linux如何解决时钟同步问题?仅需要一行命令即可。
  16. 【CSS】如何用css做一个爱心
  17. 信息学奥赛训练体系(2023.02.21)
  18. Bootstrap轮播
  19. 计算机应用和管理系统,《管理信息系统和计算机应用》.ppt
  20. 椭圆曲线加密原理与应用

热门文章

  1. keil 跳转不了(Go To Definition “XXX”失败)
  2. PyTorch 错误 RuntimeError: invalid argument 5: k not in range for dimension at /pytorch/aten/src/THC/g
  3. 仿苹果AppStore 环形下载进度条
  4. Python-OpenCV读取视频文件
  5. 龙芯3A4000服务器部署kvm虚拟机指导
  6. 传奇装备穿戴位置查询脚本,使用GetUserItemName
  7. 2021年中国留学生回国人数、求职的海归人数及海归就业情况分析:留学生回国人数增长,有留学经验的平均招聘薪酬连续三年走高[图]
  8. bottle mysql,web开发框架的选择(bottle or flask)及为autumn增加多线程支持
  9. ubuntu 下文件夹乱码
  10. 企业如何提前规划国家高新认定?