Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to avoid collection dead chain call in java

2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article is to share with you about how to avoid collection dead-chain calls in java. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

1. Preface

In the process of   development, the change of some sets will trigger the task to change other collections. In order to ensure the correct execution of the task, we should avoid endless loop calls, that is, to limit the influence relationship between collections. For fear of forgetting in the future, I would like to record here.

two。 Scene

A set affects A set.

A set affects B set, and B set affects A set.

A set affects B set, B set affects C set, and C set affects A set.

A set affects B set and C set, B set affects D set, C set affects E set, and E set affects A set.

3. Environment 3.1 preparation of development environment

JDK 1.8

SpringBoot 2.x

Mysql 8

Redis

3.2 data preparation 3.2.1 Mysql database tables and data

Dp_ process table

CREATE TABLE `dp_ process` (`ID`NAME` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'ID', `NAME` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT' name', `CODE`varchar (64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'code', `CATEGORY`CATEGORY` varchar 'type 1 = building 2 = real estate', `IN_ Cols` varchar (1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'input collection', `OUT_ Cols` varchar 'CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT' influence collection', `REMARK` varchar (1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'remarks', `ENABLED`varchar (1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'whether to open', `STATUS` int DEFAULT NULL COMMENT 'status data status: 0 = normal, 1 = delete Invalidation', `CREATED_ BY` varchar (32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'creator', `CREATED_ time` datetime DEFAULT NULL COMMENT 'creation time', `UPDATED_ BY` varchar (32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'update person', `UPDATED_ time` datetime DEFAULT NULL COMMENT 'update time', `REVISION `int DEFAULT'0' COMMENT 'optimistic lock', PRIMARY KEY (`ID`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT=' data processing'

Data in the dp_process table

INSERT INTO `gccs`.`dp _ process` (`ID`, `NAME`, `CODE`, `CATEGORY`, `OUT_ Cols`, `REMARK`, `ENABLED`, `STATUS`, `CREATED_ BY`, `CREATED_ TIME`, `UPDATED_ BY`, `UPDATED_ TIME`, `REVISION`) VALUES ('1mm,' NULL, 'NULL, 0) INSERT INTO `gccs`.`dp _ process` (`ID`, `NAME`, `CODE`, `CATEGORY`, `IN_ Cols`, `OUT_ COLS`, `REMARK`, `ENABLED`, `STATUS`, `CREATED_ BY`, `CREATED_ TIME`, `UPDATED_ BY`, `UPDATED_ TIME`, `REVISION`) VALUES ('2percent,' dating, 'dating,' ly', 'blogging,' dating, 'dating,' 1', 0, NULL, 0) INSERT INTO `gccs`.`dp _ process` (`ID`, `NAME`, `CODE`, `CATEGORY`, `OUT_ Cols`, `REMARK`, `ENABLED`, `STATUS`, `CREATED_ BY`, `CREATED_ TIME`, `UPDATED_ BY`, `UPDATED_ TIME`, `REVISION`) VALUES ('3 minutes, 'estrangement,' estrangement, 'ly',' blogs, 'estranges,' eBay,'1', 0, NULL, 0) INSERT INTO `gccs`.`dp _ process` (`ID`, `NAME`, `CODE`, `CATEGORY`, `OUT_ Cols`, `REMARK`, `ENABLED`, `STATUS`, `CREATED_ BY`, `CREATED_ TIME`, `UPDATED_ BY`, `UPDATED_ TIME`, `REVISION`) VALUES ('4mm,' Globe, 'Globe,' ly', 'Dial,' Globe, 'Globe,' 1', 0, NULL, 0) INSERT INTO `gccs`.`dp _ process` (`ID`, `NAME`, `CODE`, `CATEGORY`, `OUT_ Cols`, `REMARK`, `ENABLED`, `STATUS`, `CREATED_ BY`, `CREATED_ TIME`, `UPDATED_ BY`, `UPDATED_ TIME`, `REVISION`) VALUES ('513,' fit, 'ly',' fit, 'fit,' 1', 0, NULL, 0) 3.2.2 redis library data keyValueA [{"id": "1", "outCols": "B"}] B [{"id": "2", "outCols": "D"}, {"id": "3", "outCols": "E"}] D [{"id": "4", "outCols": "G"}, {"id": "5", "outCols": "F"}] 4. Solution method

Through the recursive way of cyclic query, comparison.

The main knowledge points involved in this example are:

Stack (stack, first in, then out)

Recursion

Redis simple add and delete operation

This paper takes the modification of method code as an example to introduce how to implement anti-dead chain calls, which is very simple.

/ * * @ create 2021-07-08 Update data processing * @ param dpProcess data processing Model * @ param updateNil full field update (this field can be ignored when added): yes: y No: n {@ link SystemConst.Whether} * @ return * / @ Override public int modify (DpProcess dpProcess String updateNil) {/ / * * omit a bunch of codes * * / input the collection to uniformly process operInclos (dpProcess, orignDpProcess.getInCols ()) / / * * omit a bunch of codes * *}

  operInclos () method: focus, mainly do a series of operations, such as data check, data update in redis, etc.

/ * * @ create input set Unified processing on 2021-7-11 14:13 * @ param dpProcess New data processing object * @ param oldClos input set * @ return * / private void operInclos (DpProcess dpProcess, String oldClos) {/ / input set in the new data processing object String inCols = dpProcess.getInCols () / / if the input set in the new data processing object has no value, skip it directly and do not operate if (StringUtils.isNotBlank (inCols)) {if (dpProcess.getInCols (). Contains (dpProcess.getOutCols () {throw new ServiceException ("the data processing process configuration input process calls the output set!") ;} / / data type conversion Set set = new HashSet (Arrays.asList (inCols.split (",")); / / iterate through the input set for (String inClo: set) {/ / the list List childFinalList = new ArrayList () that will eventually be traversed / / get the influence relationship of the current collection from redis String dpProcessJson = (String) redisUtil.get (inClo) / / if the set influence relationship stored in redis is not empty, do a simple traversal to reprocess the collection influence relation list stored in if (StringUtils.isNotBlank (dpProcessJson)) {/ / redis List children = new ArrayList () / / perform data type conversion children = JSONArray.parseArray (dpProcessJson, DpProcessVo.class); for (DpProcessVo dpProcessVo1: children) {if (dpProcess.getId (). Equals (dpProcessVo1.getId () {continue } childFinalList.add (dpProcessVo1);} / / add the set of this influence DpProcessVo dpProcess1 = new DpProcessVo (); dpProcess1.setId (dpProcess.getId ()); dpProcess1.setOutCols (dpProcess.getOutCols ()) ChildFinalList.add (dpProcess1);} / / if there is no influence relationship for this input set in redis, you can add else {DpProcessVo dpProcess1 = new DpProcessVo (); dpProcess1.setId (dpProcess.getId ()) directly. DpProcess1.setOutCols (dpProcess.getOutCols ()); childFinalList.add (dpProcess1);} / verify whether the data processing process configuration input flow calls the output set Stack nodeStack = new Stack (); / / sets the model DpProcessVo dpProcessVoTop = new DpProcessVo () DpProcessVoTop.setOutCols (inClo); dpProcessVoTop.setId (dpProcess.getId ()); nodeStack.add (dpProcessVoTop) / / traversing the data for (DpProcessVo dpProcessVo: childFinalList) {/ / whether to add an identity (default is to add, prompt if the collection is dead) boolean addFlag = true / / cycle through the stack for (DpProcessVo processVo: nodeStack) {if (processVo.getOutCols () .equals (dpProcessVo.getOutCols () {addFlag = false; break }} if (! addFlag) {throw new ServiceException ("data processing flow configuration input process invokes output set!") ;} / / push dpProcessVo to the top of the stack nodeStack.push (dpProcessVo); / / verify whether the data processing flow configuration input flow calls the output set invaldClosInfo (nodeStack) / / remove the object at the top of the stack and return it as the value of this function to nodeStack.pop ();}} / / process the collection dealNeedDeleteCols (dpProcess, oldClos, set) that needs to be deleted / / get and set the final collection name String finallyCols = StringUtils.join (set.toArray (), ","); dpProcess.setInCols (finallyCols); / / omit a bunch of operations to update redis}}

  invaldClosInfo () method: recursive depth traversal

/ * * @ create verifies that the data processing flow configuration input flow calls the output set 22:10 on 2021-7-20 * @ param nodeStack deep traversal stack * @ return void * / public void invaldClosInfo (Stack nodeStack) {/ / View the objects at the top of the stack without removing them from the stack DpProcessVo dpProcessVo = nodeStack.peek () / / find the process relationship affected by this collection from redis String dpProcessJson = (String) redisUtil.get (dpProcessVo.getOutCols ()); / / if the collection does not affect other collections, directly return if (StringUtils.isBlank (dpProcessJson)) {return } / / to get the children of a node, for a binary tree, it is to obtain the left and right child nodes of the node List children = new ArrayList (); / / the information originally stored in redis children = JSONArray.parseArray (dpProcessJson, DpProcessVo.class); / / the set relationship affected by the traversal set for (DpProcessVo dpProcessVo1: children) {boolean addFlag = true For (DpProcessVo processVo: nodeStack) {if (processVo.getOutCols (). Equals (dpProcessVo1.getOutCols () {addFlag = false; break;}} if (! addFlag) {throw new ServiceException ("data processing flow configuration input process invokes the output set!") ;} / / push dpProcessVo to the top of the stack nodeStack.push (dpProcessVo1); / / verify that the data processing flow configures the input flow to call the output set invaldClosInfo (nodeStack); / / remove the object at the top of the stack and return the object as the value of this function to nodeStack.pop () }} 5. Complete code

Record the code for future review, invocation and refactoring.

5.1 Model

  model is mainly divided into two parts: the data processing model and the simplified version of the data processing model.

  DpProcess: data processing model, Sql operation of complete data

Import com.alibaba.fastjson.annotation.JSONField;import com.baomidou.mybatisplus.annotation.*;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;import lombok.EqualsAndHashCode;import lombok.experimental.Accessors;import java.io.Serializable;import java.util.Date;/** *

* data processing *

* * @ since 2021-07-08 * / @ Data@EqualsAndHashCode (callSuper = false) @ Accessors (chain = true) @ ApiModel (value= "DpProcess object", description= "data processing") @ TableName ("dp_process") public class DpProcess implements Serializable {@ TableField (exist = false) public static final String ENABLED = "ENABLED"; @ TableField (exist = false) public static final String STATUS = "STATUS"; @ TableField (exist = false) public static final String CATEGORY = "CATEGORY" Private static final long serialVersionUID = 1L; @ ApiModelProperty (value = "ID") @ TableId (value = "ID", type = IdType.ASSIGN_ID) private String id; @ ApiModelProperty (value = "name") @ TableField ("NAME") private String name; @ ApiModelProperty (value = "Code") @ TableField ("CODE") private String code @ ApiModelProperty (value = "type 1 = building, 2 = real estate") @ TableField ("CATEGORY") private String category; @ ApiModelProperty (value = "input set") @ TableField ("IN_COLS") private String inCols; @ ApiModelProperty (value = "influence set") @ TableField ("OUT_COLS") private String outCols; @ ApiModelProperty (value = "remarks") @ TableField ("REMARK") private String remark @ ApiModelProperty (value = "whether 0: no 1: yes") @ TableField ("ENABLED") private String enabled; @ ApiModelProperty (value = "status data status: 0 = normal, 1 = delete, invalid") @ TableField (value = "STATUS", fill = FieldFill.INSERT) private Integer status; @ ApiModelProperty (value = "founder") @ TableField (value = "CREATED_BY", fill = FieldFill.INSERT) private String createdBy @ ApiModelProperty (value = "creation time") @ JSONField (format = "yyyy-MM-dd HH:mm:ss") @ TableField (value = "CREATED_TIME", fill = FieldFill.INSERT) private Date createdTime; @ ApiModelProperty (value = "updated person") @ TableField (value = "UPDATED_BY", fill = FieldFill.UPDATE) private String updatedBy @ ApiModelProperty (value = "update time") @ JSONField (format = "yyyy-MM-dd HH:mm:ss") @ TableField (value = "UPDATED_TIME", fill = FieldFill.UPDATE) private Date updatedTime; @ ApiModelProperty (value = "optimistic lock") @ Version @ TableField (value = "REVISION", fill = FieldFill.INSERT) private Integer revision;}

DpProcessVo: data processing simple model, dealing with redis data structure data.

Import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;import lombok.EqualsAndHashCode;import lombok.experimental.Accessors;@Data@EqualsAndHashCode (callSuper = false) @ Accessors (chain = true) @ ApiModel (value= "DpProcessVo object", description= "simple data processing Model") public class DpProcessVo {@ ApiModelProperty (value= "ID") private String id; @ ApiModelProperty (value= "influence set") private String outCols;} 5.2 Controller

UpdateNil: let users choose which update method to use, or split the interface into two, depending on personal habits.

/ * * @ create 2021-07-08 Update data processing * @ param dpProcess data processing Model * @ param updateNil full field update (this field can be ignored when added): yes: y No: n {@ link SystemConst.Whether} * @ return * / @ ApiOperation (value= "update" Notes = "update") @ PostMapping ("/ modify") public Result modify (@ ApiParam (name = "dpProcess", value = "data processing model", required = true) @ RequestBody DpProcess dpProcess, @ ApiParam (name = "updateNil") Value = "full field update (this field can be ignored when added): yes: y No: no or no") @ RequestParam (required = false) String updateNil) {int addResult = dpProcessService.modify (dpProcess, updateNil) If (addResult > 0) {return new Result (CommonCode.SUCCESS, "updated successfully!") ;} return new Result (CommonCode.FAIL, "update failed!") ;} 5.3 Service

There's nothing to say, it's just an interface.

/ * * @ create 2021-07-08 Update data processing * @ param dpProcess data processing Model * @ param updateNil full field update (this field can be ignored when added): yes: y No: n {@ link SystemConst.Whether} * @ return * / int modify (DpProcess dpProcess, String updateNil); 5.4 Service implementation class

  DpRecord: data processing records, which are not the focus of this article, can be ignored here. The relevant instructions are to be withdrawn in the data flow processing article.

/ * * @ create 2021-07-08 Update data processing * @ param dpProcess data processing Model * @ param updateNil full field update (this field can be ignored when added): yes: y No: n {@ link SystemConst.Whether} * @ return * / @ Override public int modify (DpProcess dpProcess String updateNil) {if (dpProcess = = null) {throw new ServiceException ("data processing model cannot be empty!") ;} / / go update method / / query data processing details through id DpProcess orignDpProcess = this.detail (dpProcess.getId ()); if (dpProcess = = null) {throw new ServiceException ("data processing model information cannot be empty!") ;} / / if the current task already exists, cancel if ("0" .equals (dpProcess.getEnabled () {if (defaultSchedulingConfigurer.hasTask (dpProcess.getId () {defaultSchedulingConfigurer.cancelTriggerTask (dpProcess.getId ()) } / / check whether there are any data processing records to be performed in the database according to the data processing ID DpRecord dpRecord = dpRecordService.getNeedExecRecordByDppId (dpProcess.getId ()) / / if the data processing record information is empty, add if (dpRecord! = null) {/ / set the end time to the current time dpRecord.setEndTime (new Date ()); / / run failed dpRecord.setSucceed ("2") DpRecord.setFailedResult ("user cancels the operation");} / / A pair of data processing records are updated or saved dpRecordService.addOrUpdate (dpRecord, null);} / / restrict that the output set cannot be empty dpProcess.setOutCols (StringUtils.isNotBlank (dpProcess.getOutCols ())? DpProcess.getOutCols (): orignDpProcess.getOutCols (); if (StringUtils.isBlank (dpProcess.getOutCols () {throw new ServiceException ("data influence set cannot be empty!") ;} / / input set uniformly handles operInclos (dpProcess, orignDpProcess.getInCols ()); / / full field update if (SystemConst.Whether.Yes.getCode (). Equals (updateNil)) {if (StringUtils.isBlank (dpProcess.getRemark () {throw new ServiceException ("data processing remarks cannot be empty!") ;} / / remarks cannot be less than 20 words if (dpProcess.getRemark () .length ()

< 20){ throw new ServiceException("数据处理备注不能小于20字!"); } return dpProcessMapper.alwaysUpdateSomeColumnById(dpProcess); } // 数据处理代码自动填充 dpProcess.setCode(StringUtils.isBlank(dpProcess.getCode()) ? orignDpProcess.getCode() : dpProcess.getCode()); return dpProcessMapper.updateById(dpProcess); } operInclos() : 处理输入集合的方法 /** * @create 输入集合统一处理 2021/7/11 14:13 * @param dpProcess 新数据处理对象 * @param oldClos 原数据处理对象中的而输入集合 * @return */private void operInclos(DpProcess dpProcess, String oldClos) { // 新数据处理对象中的输入集合 String inCols = dpProcess.getInCols(); // 若新数据处理对象中的输入集合没有值,则直接跳过,不进行操作 if(StringUtils.isNotBlank(inCols)){ if(dpProcess.getInCols().contains(dpProcess.getOutCols())){ throw new ServiceException("数据处理流程配置输入流程调用了输出集合!"); } // 数据类型转换 Set set = new HashSet(Arrays.asList(inCols.split(","))); // 循环遍历输入集合 for (String inClo : set) { // 最终需要遍历的list List childFinalList = new ArrayList(); // 从redis中获取当前集合的影响关系 String dpProcessJson = (String) redisUtil.get(inClo); // 如果redis中存储的集合影响关系不为空,做简单的遍历去重处理 if(StringUtils.isNotBlank(dpProcessJson)){ // redis中存储的集合影响关系列表 List children = new ArrayList(); // 进行数据类型转换 children = JSONArray.parseArray(dpProcessJson, DpProcessVo.class); for (DpProcessVo dpProcessVo1 : children) { if(dpProcess.getId().equals(dpProcessVo1.getId())){ continue; } childFinalList.add(dpProcessVo1); } // 添加本次影响的集合 DpProcessVo dpProcess1 = new DpProcessVo(); dpProcess1.setId(dpProcess.getId()); dpProcess1.setOutCols(dpProcess.getOutCols()); childFinalList.add(dpProcess1); } // 如果redis中没有此输入集合的影响关系,则可以直接进行添加 else{ DpProcessVo dpProcess1 = new DpProcessVo(); dpProcess1.setId(dpProcess.getId()); dpProcess1.setOutCols(dpProcess.getOutCols()); childFinalList.add(dpProcess1); } // 验证数据处理流程配置输入流程是否调用了输出集合 Stack nodeStack = new Stack(); // 设置模型 DpProcessVo dpProcessVoTop = new DpProcessVo(); dpProcessVoTop.setOutCols(inClo); dpProcessVoTop.setId(dpProcess.getId()); nodeStack.add(dpProcessVoTop); // 遍历需要进行死链校验的数据 for (DpProcessVo dpProcessVo : childFinalList) { // 是否添加标识(默认为添加,如果集合为死链,则进行提示) boolean addFlag = true; // 循环遍历栈 for (DpProcessVo processVo : nodeStack) { if(processVo.getOutCols().equals(dpProcessVo.getOutCols())){ addFlag = false; break; } } if(!addFlag){ throw new ServiceException("数据处理流程配置输入流程调用了输出集合!"); } // 将dpProcessVo推到这个堆栈的顶部 nodeStack.push(dpProcessVo); // 验证数据处理流程配置输入流程是否调用了输出集合 invaldClosInfo(nodeStack); // 移除此堆栈顶部的对象并将该对象作为此函数的值返回 nodeStack.pop(); } } // 处理需要删除的集合 dealNeedDeleteCols(dpProcess, oldClos, set); // 获取并设置最终的集合名称 String finallyCols = StringUtils.join(set.toArray(), ","); dpProcess.setInCols(finallyCols); // 能走到这一步,说明所有的集合没有问题,可以进行更新操作了(再一次遍历是为了和上面的校验分开,避免部分数据被更新) for (String inClo : set) { List dpProcessVoList = new ArrayList(); // 首先获取当前集合影响的数据处理对象 String dpProcessJson = (String) redisUtil.get(inClo); if(StringUtils.isBlank(dpProcessJson)){ DpProcessVo dpProcessVo = new DpProcessVo(); dpProcessVo.setId(dpProcess.getId()); dpProcessVo.setOutCols(dpProcess.getOutCols()); dpProcessVoList.add(dpProcessVo); // 进行数据的存储 redisUtil.set(inClo, JSONArray.toJSON(dpProcessVoList).toString()); continue; } // redis中原来存储的信息 List dpProcessVos = JSONArray.parseArray(dpProcessJson, DpProcessVo.class); // 把数据处理对象转换为HashSet HashSet hashSet = new HashSet(dpProcessVos); // 当前集合影响的 其他集合列表 List childFinalList = new ArrayList(); // 遍历redis中存储的集合影响关系,并进行简单去重处理 for (DpProcessVo dpProcessVo : hashSet) { if(dpProcessVo.getId().equals(dpProcess.getId())){ continue; } childFinalList.add(dpProcessVo); } // 添加上本次影响的集合 DpProcessVo dpProcessVo = new DpProcessVo(); dpProcessVo.setId(dpProcess.getId()); dpProcessVo.setOutCols(dpProcess.getOutCols()); // 添加当前数据数据对象 childFinalList.add(dpProcessVo); // 进行数据的存储 redisUtil.set(inClo, JSONArray.toJSON(childFinalList).toString()); } }} invaldClosInfo() : 验证数据处理流程配置输入流程是否调用了输出集合 /** * @create 验证数据处理流程配置输入流程是否调用了输出集合 2021/7/20 22:10 * @param nodeStack 深度遍历栈 * @return void */public void invaldClosInfo(Stack nodeStack) { // 查看此堆栈顶部的对象而不将其从堆栈中移除 DpProcessVo dpProcessVo = nodeStack.peek(); // 从redis中查找此集合影响的流程关系 String dpProcessJson = (String) redisUtil.get(dpProcessVo.getOutCols()); // 如果集合没有影响其他集合,则直接返回 if(StringUtils.isBlank(dpProcessJson)){ return; } //获得节点的子节点,对于二叉树就是获得节点的左子结点和右子节点 List children = new ArrayList(); // redis中原来存储的信息 children = JSONArray.parseArray(dpProcessJson, DpProcessVo.class); // 遍历集合影响的集合关系 for (DpProcessVo dpProcessVo1 : children) { boolean addFlag = true; for (DpProcessVo processVo : nodeStack) { if(processVo.getOutCols().equals(dpProcessVo1.getOutCols())){ addFlag = false; break; } } if(!addFlag){ throw new ServiceException("数据处理流程配置输入流程调用了输出集合!"); } // 将dpProcessVo推到这个堆栈的顶部 nodeStack.push(dpProcessVo1); // 验证数据处理流程配置输入流程是否调用了输出集合 invaldClosInfo(nodeStack); // 移除此堆栈顶部的对象并将该对象作为此函数的值返回 nodeStack.pop(); }} dealNeedDeleteCols() : 主要处理--原数据为 A 集合影响 B 集合,修改为 C 集合影响了 B 集合,此时需要删除 A 对 B的影响关系 /** * @create 处理需要删除的集合 2021/7/20 17:58 * @param dpProcess 数据处理模型 * @param oldClos 原来的数据处理模型中的集合信息 * @param set 最新的集合名称信息 * @return void */private void dealNeedDeleteCols(DpProcess dpProcess, String oldClos, Set set) { if(StringUtils.isBlank(oldClos)){ return; } // 获取去重后的集合数组 List newColsList = new ArrayList(set); // 原来的集合数组 List oldColsList = Arrays.asList(oldClos.split(",")); // 获取两个集合的差集 List reduceList = oldColsList.stream().filter(item ->

! newColsList.contains (item). Collection (toList ()); if (reduceList = = null | | reduceList.size () = 0) {return;} for (String clos: reduceList) {/ / get the collection String dpProcessJson = (String) redisUtil.get (clos) in redis; if (StringUtils.isBlank (dpProcessJson)) {continue } / / the information originally stored in redis List dpProcessVos = JSONArray.parseArray (dpProcessJson, DpProcessVo.class); / / traverses the process affected in the deleted collection ID HashSet hashSet = new HashSet (dpProcessVos); Iterator it = hashSet.iterator (); while (it.hasNext ()) {DpProcessVo dpProcessVo = it.next () If (dpProcessVo.getId (). Equals (dpProcess.getId () {it.remove ();}} / / if the process affected by the current collection is empty, delete if (hashSet.isEmpty ()) {/ / data storage redisUtil.delete (clos); continue RedisUtil.set (clos, JSONArray.toJSON (hashSet.toArray ()). ToString ());}} 6. test

  can be tested in a variety of ways, such as unit testing. This article provides simple test data.

{"category": "ly", "code": "F", "createdBy": "," createdTime ": null," enabled ":" 1 "," id ":" 5 "," inCols ":" D "," name ":" F "," outCols ":" L "," remark ":" F "," revision ": 0," status ": 0 "updatedBy": "updatedTime": null} Thank you for reading! This is the end of this article on "how to avoid collection dead-chain calls in java". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it out for more people to see!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report