精华内容
下载资源
问答
  • 以及输入两个节点ID号,判断他们是否直接相连。分布解析这题目要求。1、先读取txt文件中的数据,用ArrayList<Integer[]>将每行数据存储下来。然后给这些数据构建数据关系。去读这...

    具体描述:txt文件中存储n个节点直接的联系,形如1,2表示节点1和节点2直接联系,或者说他们是邻居。有很多组这样的数据,要求将这些节点读出来进行存储。然后实现输入节点号,输出它的邻居节点。以及输入两个节点ID号,判断他们是否直接相连。

    分布解析这个题目要求。1、先读取txt文件中的数据,用ArrayList<Integer[]>将每一行数据存储下来。然后给这些数据构建数据关系。去读这个ArrayList中的数据,我们要根据节点的ID号去找它的邻居。根据关键字去找指定的数据。在Java中可以使用HashMap<Key, Value>这样的存储结构来存储。将每个节点的ID号当作Key,它的邻居节点组当作Value,但是考虑到这个节点的邻居有多个,所以我们使用HashSet进行存储。即存储数据的结构可认为是:HashMap<Integer, HashSet<Integer>>。

    参考代码如下:

    public static HashMap<Integer, HashSet<Integer>> 
    	                      getRelationMap(ArrayList<Integer[]> dataList){
    		
    		HashMap<Integer, HashSet<Integer>>  relationMap =
    				new HashMap<Integer, HashSet<Integer>>();
    		int i = 0;
    		Integer[] intArray = null;
    		Integer nodeID1 = 0;
    		Integer nodeID2 = 0;
    		for(i = 0; i < dataList.size(); i ++) {
    			intArray = dataList.get(i);
    			nodeID1 = intArray[0];
    			nodeID2 = intArray[1];
    			constructRelationMap(relationMap, nodeID1, nodeID2);
    			constructRelationMap(relationMap, nodeID2, nodeID1);
    		}
    		return relationMap;
    	}
    	private static void 
    	constructRelationMap(HashMap<Integer, HashSet<Integer>>  relationMap,
    			Integer nodeID1, Integer nodeID2) {
    		HashSet<Integer> tmpSet = null;
    		if(!relationMap.containsKey(nodeID1)) {
    			tmpSet = new HashSet<Integer>();
    			tmpSet.add(nodeID2);
    			relationMap.put(nodeID1, tmpSet);
    		}else {
    			tmpSet = relationMap.get(nodeID1);
    			tmpSet.add(nodeID2);
    		}
    	}
    	public static ArrayList<Integer[]> getData(String fileName) throws IOException{
    		ArrayList<Integer[]> dataList = new ArrayList<Integer[]>();
    		File file = new File(fileName);
    		BufferedReader reader = new BufferedReader(new FileReader(file));
    		String tempString = null;
    		String[] strArray = null;
    		Integer[] intArray = null;
    		while ((tempString = reader.readLine()) != null) {
    			strArray = tempString.split(",");
    			intArray = new Integer[]{Integer.parseInt(strArray[0]),
    					Integer.parseInt(strArray[1])};
    			dataList.add(intArray);
    		}
    		reader.close();
    		return dataList;
    	}

    2、实现要求的两个功能,只要根据上面对数据的存储方式,根据HashMap键值对的特征去查找即可。参考代码如下:

    private static void getNeighbors(HashMap<Integer, HashSet<Integer>> relationMap,
    			Integer nodeID1) {
    		System.out.print(nodeID1 + "'s neighbors are:");
    		HashSet<Integer> myset = relationMap.get(nodeID1);
    		Iterator<Integer> it = myset.iterator();
    		Integer neighborID = 0;
    		while(it.hasNext()) {
    			neighborID = it.next();
    			System.out.print(neighborID + ",");
    		}
    		System.out.println();
    	}
    	
    	public static boolean isNodeConnected(HashMap<Integer, HashSet<Integer>> relationMap,
    			Integer nodeID1, Integer nodeID2) {
    		return relationMap.get(nodeID1).contains(nodeID2);
    	}


    以上就是这篇文章的主要内容。欢迎各位提出意见。让我们一起学习进步!


    展开全文
  • 最近有些同学过来问我如何判断zookeeper的节点是持久节点还是临时节点?其实很简单,接下来我们就来看看判断方法。   zookeeper 持久节点:该数据节点被创建后,就会一直存在于zookeeper服务器上,直到有删除操作...

    最近有些同学过来问我如何判断zookeeper的节点是持久节点还是临时节点?其实很简单,接下来我们就来看看判断方法。

     

    zookeeper 持久节点:该数据节点被创建后,就会一直存在于zookeeper服务器上,直到有删除操作来主动删除这个节点。

     

    zookeeper临时节点:临时节点的生命周期和客户端会话绑定在一起,客户端会话失效,则这个节点就会被自动清除。

     

     

     

    我们执行 sh zkCli.sh -server 127.0.0.1:2181登录zookeeper,分别创建一个持久节点和临时节点。

     

    create  /yujie-persistent   ""   //创建持久节点

     

    create -e /yujie-ephemeral  ""  // 创建临时节点

     

     

     

     

     

    接下来我们用get命令 查看节点的Stat数据结构信息

     

     

     

    其中有一个字段是ephemeralOwner意思是这个节点的临时拥有者

     

    当ephemeralOwner 值不为0时,表明这个节点是临时节点,值为会话id.

     

    当ephemeralOwner 值为0时,表明这个节点是持久节点。.

     

    =============================================

    节点有两个维度,一个是永久的还是临时的,另一个是否有序。组合成的四种类型如下:

    1:PERSISTENT                                //  持久化节点

    2:PERSISTENT_SEQUENTIAL       //  持久化排序节点

    3:EPHEMERAL                                 //  临时节点

    4:EPHEMERAL_SEQUENTIAL        //  临时排序节点

    永久节点:节点创建后会被持久化,只有主动调用delete方法的时候才可以删除节点。

    临时节点:节点创建后在创建者超时连接或失去连接的时候,节点会被删除。临时节点下不能存在字节点。

    排序节点:创建的节点名称后自动添加序号,如节点名称为"node-",自动添加为"node-1",顺序添加为"node-2"...
    --------------------- 

    原文:https://blog.csdn.net/daobaliangbanana2/article/details/81626977

    原文:https://blog.csdn.net/u011784767/article/details/74529887

     

    展开全文
  • 二叉树中删除一个节点

    万次阅读 2014-06-15 23:06:34
    二叉树的删除可以算是二叉树最为复杂的操作,删除的时候要考虑到很多种情况: 1.被删除的节点是叶子节点 2.被删除的节点只有左...在二叉树中想要删除一个节点,首先需要找到这个节点,由于二叉树在插入节点的时候会遵
     二叉树的删除可以算是二叉树最为复杂的操作,删除的时候要考虑到很多种情况:
    1.被删除的节点是叶子节点
    2.被删除的节点只有左孩子节点
    3.被删除的节点只有右孩子节点
    4.被删除的有两个孩子节点
     
    所以在删除的时候,这4种情况都必须考虑进去,并且这4中情况之下,还会有细的划分,下面就细说怎么删除。
     
    在二叉树中想要删除一个节点,首先需要找到这个节点,由于二叉树在插入节点的时候会遵循一个原则,就是利用节点的值来判断
    节点将被插入的位置(或者给节点加一个key,用key来判断)。从根节点开始往下走,比当前节点小(或等于)的会被插入到
    当前节点的左边,比当前节点大的会被插入到当前节点的右边。所以,根据根据二叉树的插入规则来找出即将被删除的节点。代码如下; 
    //保存当前节点
    		Node parent=root;//保存当前节点父节点
    		boolean isLeft=true;//记录是否是左几点
    		//定位到将被删除的节点 
    		while(key!=curr.key){
    			if(key<=curr.key){
    				isLeft=true;//经过左节点
    				if(curr.left!=null){
    					parent=curr;
    					curr=curr.left;
    				}
    			}else{
    				isLeft=false;//经过右节点
    				if(curr.right!=null){
    					parent=curr;
    					curr=curr.right;
    				}
    			}
    			if(curr==null){
    				return false;
    			}
    }


      在这断代码中,首先定义了两个引用,一个用来代表当前节点,一个用来代表当前节点的父节点,然后进入一个while循环,
    循环里,首先会根据key的比较来决定该往左走还是往右走,如果往左走,就说明当前节点是它父节点的左孩子了,然后把
    ifLeft设置为true,如果往右走,同理就把isLeft设置为false(isLeft在后面会被用到)。现在,往下走得方向
    已经确定了,然后该就判断所经过的节点(即当前节点)是否为空,如果该节点的左右都为空,就说明你要删的节点没有找到,程序
    将会返回false。如果如果当前节点左孩子不为空,就把当前节点等于它的左孩子,相当于又往下走了一步。正个寻找的过程,就是
    不停的根据值判断,不停的往下走,直到满足条件,循环停止。这时,当前节点就保存的是即将被删除节点的引用,并且还知道被删除的
    父节点是谁,被删除节点是它父节点的哪边的孩纸都知道。
    找到了被删除的节点,下面就来看,要怎么删除它。
    1.如果被删除的节点是叶子节点,用代码表示就是
    if(curr.left==null&&curr.right==null){
    			if(curr==root){
    				root=null;
    			}else if(isLeft){
    				parent.left=null;
    			}else{
    				parent.right=null;
    			}
    		}


    可以看出,情况又被细分了三种,当被删除节点即是叶子节点又是根节点,这是树中就只有一个根节点了,就直接删除
    下面两种是判断的是,当前被删除节点是其父节点哪边的节点。

    2.被删除的节点只有左孩子节点
    if(curr.right==null){
    			if(curr==root){
    				root=root.left;
    			}else if(isLeft){
    				parent.left=curr.left;
    			}else{
    				parent.right=curr.left;
    			}
    		}
    当被删除的节点只有一个孩子时,就只需要用它的孩子节点,把它自己给替换下去。具体的还是跟上面一样,需要分三种情况
    来考虑,如果是根节点,就直接把根节点指向根节点的左孩子,这样一来,原来的根节点就无法访问到,会被虚拟机自动回收掉。
    同理下面也一样。

     
    3.被删除的节点只有右孩子节点,这种情况跟第二种情况类似
      
    if(curr.left==null){
    			if(curr==root){
    				root=root.right;
    			}else if(isLeft){
    				parent.left=curr.right;
    			}else{
    				parent.right=curr.right;
    			}
    		}


     
    4.被删除的有两个孩子节点,这种情况最复杂,因为要考虑到删除之后顺序不能乱。
    所以这种类型的节点要删除,如果直接删,真个树的大小顺序就乱了,所以需要考虑,在树中找到一个合适的节点来把这个节点
    给替换掉,用这种方法来保持整个数的稳定。所以又一个问题又来了了,该找哪个节点来替换它?结论是,需要在树中找出所有比
    被删除节点的值大的所有数,并在这些数中找出一个最小的数来。听起来很拗,如果把它用图形来描述的话,就是,从被删除的节点出发
    经过它的右节点,然后右节点最左边的叶子节点就是我们要找的,它有一个专业名词叫中序后继节点。下面专门来写一个方法来找它:
      
       
     public Node getSuccessor(Node delNode){  //参数为被删除的节点
    			//定义一个当前节点的引用,直接让往下走一步,走到被删除节点的右节点
    			Node curr=delNode.right; 
    			Node successor=curr;  //用来指向中级后续节点
    			Node sucParent=null; //用来指向中级后续节点的父节点
    			while(curr!=null){  
    				sucParent=successor;
    				successor=curr;
    				curr=curr.left;
    			}
    			//循环停止,中级后续节点被找出
    			if(successor!=delNode.right){
    				//将后继节点的子节点(只可能有右节点)替补到后继节点的位置上
    				sucParent.left=successor.right;
    				//将被删除的右孩子连接到后继节点的右节点上
    				successor.right=delNode.right;
    				//将被删除的左孩子连接到后继节点的右节点上(就是用后继节点替换掉被删除的节点)
    			}
    			return successor;
    		}



    由于过程比较复杂,这里用图来表示



    删除节点的完成代码:

    /**
    	 * 删除节点
    	 * @param key
    	 */
    	public boolean delete(int key){
    		Node curr=root;//保存当前节点
    		Node parent=root;//保存当前节点父节点
    		boolean isLeft=true;//记录是否是左几点
    		//定位到将被删除的节点 
    		while(key!=curr.key){
    			if(key<=curr.key){
    				isLeft=true;//经过左节点
    				if(curr.left!=null){
    					parent=curr;
    					curr=curr.left;
    				}
    			}else{
    				isLeft=false;//经过右节点
    				if(curr.right!=null){
    					parent=curr;
    					curr=curr.right;
    				}
    			}
    			if(curr==null){
    				return false;
    			}
    		}
    		//如果被删除节点是叶子节点
    		if(curr.left==null&&curr.right==null){
    			if(curr==root){
    				root=null;
    			}else if(isLeft){
    				parent.left=null;
    			}else{
    				parent.right=null;
    			}
    		//如果被删除节点只有左节点
    		}else if(curr.right==null){
    			if(curr==root){
    				root=root.left;
    			}else if(isLeft){
    				parent.left=curr.left;
    			}else{
    				parent.right=curr.left;
    			}
    		//如果被删除节点只有右节点
    		}else if(curr.left==null){
    			if(curr==root){
    				root=root.right;
    			}else if(isLeft){
    				parent.left=curr.right;
    			}else{
    				parent.right=curr.right;
    			}
    		}else{
    			Node successor=getSuccessor(curr);
    			//将后继节点与被删除的父节点进行连接,完成整个替换过程
    			if(curr==root){
    				root=successor;
    			}else if(curr==parent.left){
    				parent.left=successor;
    			}else{
    				parent.right=successor;
    			}
    			successor.left=curr.left;
    		}
    		return true;
    		
    	}
    	
    	public Node getSuccessor(Node delNode){
    		Node curr=delNode.right;
    		Node successor=curr;
    		Node sucParent=null;
    		while(curr!=null){
    			sucParent=successor;
    			successor=curr;
    			curr=curr.left;
    		}
    		if(successor!=delNode.right){
    			//将后继节点的子节点(只可能有右节点)替补到后继节点的位置上
    			sucParent.left=successor.right;
    			//将被删除的右孩子连接到后继节点的右节点上
    			successor.right=delNode.right;
    			//将被删除的左孩子连接到后继节点的右节点上(就是用后继节点替换掉被删除的节点)
    		}
    		return successor;
    	}


    展开全文
  • activiti根据当前节点获取下一个UseTask节点

    万次阅读 热门讨论 2017-08-10 17:15:23
    以前写过一篇文章activiti根据当前节点获取下一个节点信息,当时的需求只是需要获取下一个节点而已,并没有要求获得什么类型的节点,所以下一个节点可能是任何节点,在最近的项目中的需求是根据当前的节点获取下一个...

    以前写过一篇文章activiti根据当前节点获取下一个节点信息,当时的需求只是需要获取下一个节点而已,并没有要求获得什么类型的节点,所以下一个节点可能是任何节点,在最近的项目中的需求是根据当前的节点获取下一个UseTask节点,为当前审批人选择下一个审批人提示,所以前面的文章所给出的信心就不能够实现当前功能。
    所以本文所述为获取下一个任务节点。根据上一篇文章,可以获取到下一个节点的信息,如果我们获取到的节点是Exclusive Gateway,那么再根据这个节点再往下查询直到下一个节点是useTask为止,那么遇到GateWay就需要根据条件对流程进行判断,获取el表达式,再根据条件得到流程走的是哪一条线。

    一、测试流程图:

    这里写图片描述
    流程图中最重要的是需要设置gateWay的Id值–这个Id值与gatway流出的flow的el表达式的key要对应(不然程序在执行中会出错)。
    这里写图片描述
    这里写图片描述
    这里写图片描述
    下面就是具体的执行程序:

    /** 
         * 获取下一个用户任务信息  
         * @param String taskId     任务Id信息  
         * @return  下一个用户任务用户组信息  
         * @throws Exception 
         */  
        public TaskDefinition getNextTaskInfo(String taskId) throws Exception {  
    
            ProcessDefinitionEntity processDefinitionEntity = null;  
    
            String id = null;  
    
            TaskDefinition task = null;  
    
            //获取流程实例Id信息   
            String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();  
    
            //获取流程发布Id信息   
            String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();  
    
            processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)  
                    .getDeployedProcessDefinition(definitionId);  
    
            ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();  
    
            //当前流程节点Id信息   
            String activitiId = execution.getActivityId();    
    
            //获取流程所有节点信息   
            List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();   
    
            //遍历所有节点信息   
            for(ActivityImpl activityImpl : activitiList){      
                id = activityImpl.getId();     
                if (activitiId.equals(id)) {
                    //获取下一个节点信息   
                    task = nextTaskDefinition(activityImpl, activityImpl.getId(), null, processInstanceId); 
                    break;
                }
            }  
            return task;  
        }  
    
        /**  
         * 下一个任务节点信息,  
         *  
         * 如果下一个节点为用户任务则直接返回,  
         *  
         * 如果下一个节点为排他网关, 获取排他网关Id信息, 根据排他网关Id信息和execution获取流程实例排他网关Id为key的变量值,  
         * 根据变量值分别执行排他网关后线路中的el表达式, 并找到el表达式通过的线路后的用户任务
         * @param ActivityImpl activityImpl     流程节点信息  
         * @param String activityId             当前流程节点Id信息  
         * @param String elString               排他网关顺序流线段判断条件
         * @param String processInstanceId      流程实例Id信息  
         * @return  
         */    
        private TaskDefinition nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString, String processInstanceId){   
    
            PvmActivity ac = null;
    
            Object s = null;
    
            // 如果遍历节点为用户任务并且节点不是当前节点信息
            if ("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
                // 获取该节点下一个节点信息
                TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior())
                        .getTaskDefinition();
                return taskDefinition;
            } else {
                // 获取节点所有流向线路信息
                List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
                List<PvmTransition> outTransitionsTemp = null;
                for (PvmTransition tr : outTransitions) {
                    ac = tr.getDestination(); // 获取线路的终点节点
                    // 如果流向线路为排他网关
                    if ("exclusiveGateway".equals(ac.getProperty("type"))) {
                        outTransitionsTemp = ac.getOutgoingTransitions();
    
                        // 如果网关路线判断条件为空信息
                        if (StringUtils.isEmpty(elString)) {
                            // 获取流程启动时设置的网关判断条件信息
                            elString = getGatewayCondition(ac.getId(), processInstanceId);
                        }
    
                        // 如果排他网关只有一条线路信息
                        if (outTransitionsTemp.size() == 1) {
                            return nextTaskDefinition((ActivityImpl) outTransitionsTemp.get(0).getDestination(), activityId,
                                    elString, processInstanceId);
                        } else if (outTransitionsTemp.size() > 1) { // 如果排他网关有多条线路信息
                            for (PvmTransition tr1 : outTransitionsTemp) {
                                s = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
                                // 判断el表达式是否成立
                                if (isCondition(ac.getId(), StringUtils.trim(s.toString()), elString)) {
                                    return nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, elString,
                                            processInstanceId);
                                }
                            }
                        }
                    } else if ("userTask".equals(ac.getProperty("type"))) {
                        return ((UserTaskActivityBehavior) ((ActivityImpl) ac).getActivityBehavior()).getTaskDefinition();
                    } else {
                    }
                }
                return null;
            }
        }  
    
        /** 
         * 查询流程启动时设置排他网关判断条件信息  
         * @param String gatewayId          排他网关Id信息, 流程启动时设置网关路线判断条件key为网关Id信息  
         * @param String processInstanceId  流程实例Id信息  
         * @return 
         */  
        public String getGatewayCondition(String gatewayId, String processInstanceId) {  
            Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();
            Object object= runtimeService.getVariable(execution.getId(), gatewayId);
            return object==null? "":object.toString();  
        }  
    
        /** 
         * 根据key和value判断el表达式是否通过信息  
         * @param String key    el表达式key信息  
         * @param String el     el表达式信息  
         * @param String value  el表达式传入值信息  
         * @return 
         */  
        public boolean isCondition(String key, String el, String value) {  
            ExpressionFactory factory = new ExpressionFactoryImpl();    
            SimpleContext context = new SimpleContext();    
            context.setVariable(key, factory.createValueExpression(value, String.class));    
            ValueExpression e = factory.createValueExpression(context, el, boolean.class);    
            return (Boolean) e.getValue(context);  
        }  

    单元测试:

    @Test
        public void nextTaskInfo() throws Exception{
            ActivitiNextTask task = new ActivitiNextTask();
            String processInstanceId = "387905";
            TaskDefinition nextTaskGroup = task.getNextTaskInfo(processInstanceId);
            System.out.println(nextTaskGroup.getKey());
        }

    通过测试能够正确的根据条件获取下一个usetask节点信息。
    那么又存在另一种情况,如果流程中存在连续多个GateWay,那么上述的程序获取下一个节点就不正确了,所以需要在上述的程序上在进行修改。

    二、流程图二

    这里写图片描述
    在费用报销申请后面有两个GateWay,当流程到达费用报销申请时需要判断下一步是审批还是审批(部门经理)对于第二个GateWay需要修改的是:
    这里写图片描述
    这里写图片描述
    然后再对上述的代码进行修改:

    private TaskService taskService = ProcessEngines.getDefaultProcessEngine().getTaskService() ;
    
        private RuntimeService runtimeService = ProcessEngines.getDefaultProcessEngine().getRuntimeService();
    
        private RepositoryService repositoryService = ProcessEngines.getDefaultProcessEngine().getRepositoryService();
    
    
        /** 
         * 获取下一个用户任务信息  
         * @param String taskId     任务Id信息  
         * @return  下一个用户任务用户组信息  
         * @throws Exception 
         */  
        public TaskDefinition getNextTaskInfo(String processInstanceId) throws Exception {  
    
            ProcessDefinitionEntity processDefinitionEntity = null;  
    
            String id = null;  
    
            TaskDefinition task = null;  
    
            //获取流程实例Id信息   
            //String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();  
    
            //获取流程发布Id信息   
            String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();  
    
            processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)  
                    .getDeployedProcessDefinition(definitionId);  
    
            ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();  
    
            //当前流程节点Id信息   
            String activitiId = execution.getActivityId();    
    
            //获取流程所有节点信息   
            List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();   
    
            //遍历所有节点信息   
            for(ActivityImpl activityImpl : activitiList){      
                id = activityImpl.getId();     
                if (activitiId.equals(id)) {
                    //获取下一个节点信息   
                    task = nextTaskDefinition(activityImpl, activityImpl.getId(), null, processInstanceId); 
                    break;
                }
            }  
            return task;  
        }  
    
        /**  
         * 下一个任务节点信息,  
         *  
         * 如果下一个节点为用户任务则直接返回,  
         *  
         * 如果下一个节点为排他网关, 获取排他网关Id信息, 根据排他网关Id信息和execution获取流程实例排他网关Id为key的变量值,  
         * 根据变量值分别执行排他网关后线路中的el表达式, 并找到el表达式通过的线路后的用户任务
         * @param ActivityImpl activityImpl     流程节点信息  
         * @param String activityId             当前流程节点Id信息  
         * @param String elString               排他网关顺序流线段判断条件
         * @param String processInstanceId      流程实例Id信息  
         * @return  
         */    
        private TaskDefinition nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString, String processInstanceId){   
    
            PvmActivity ac = null;
    
            Object s = null;
    
            // 如果遍历节点为用户任务并且节点不是当前节点信息
            if ("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
                // 获取该节点下一个节点信息
                TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior())
                        .getTaskDefinition();
                return taskDefinition;
            } else if("exclusiveGateway".equals(activityImpl.getProperty("type"))){// 当前节点为exclusiveGateway
                List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
                //outTransitionsTemp = ac.getOutgoingTransitions();
    
                // 如果网关路线判断条件为空信息
    //          if (StringUtils.isEmpty(elString)) {
                    // 获取流程启动时设置的网关判断条件信息
                    elString = getGatewayCondition(activityImpl.getId(), processInstanceId);
    //          }
                // 如果排他网关只有一条线路信息
                if (outTransitions.size() == 1) {
                    return nextTaskDefinition((ActivityImpl) outTransitions.get(0).getDestination(), activityId,
                            elString, processInstanceId);
                } else if (outTransitions.size() > 1) { // 如果排他网关有多条线路信息
                    for (PvmTransition tr1 : outTransitions) {
                        s = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
                        // 判断el表达式是否成立
                        if (isCondition(activityImpl.getId(), StringUtils.trim(s.toString()), elString)) {
                            return nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, elString,
                                    processInstanceId);
                        }
    
                    }
                }
            }else {
                // 获取节点所有流向线路信息
                List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
                List<PvmTransition> outTransitionsTemp = null;
                for (PvmTransition tr : outTransitions) {
                    ac = tr.getDestination(); // 获取线路的终点节点
                    // 如果流向线路为排他网关
                    if ("exclusiveGateway".equals(ac.getProperty("type"))) {
                        outTransitionsTemp = ac.getOutgoingTransitions();
    
                        // 如果网关路线判断条件为空信息
                        if (StringUtils.isEmpty(elString)) {
                            // 获取流程启动时设置的网关判断条件信息
                            elString = getGatewayCondition(ac.getId(), processInstanceId);
                        }
    
                        // 如果排他网关只有一条线路信息
                        if (outTransitionsTemp.size() == 1) {
                            return nextTaskDefinition((ActivityImpl) outTransitionsTemp.get(0).getDestination(), activityId,
                                    elString, processInstanceId);
                        } else if (outTransitionsTemp.size() > 1) { // 如果排他网关有多条线路信息
                            for (PvmTransition tr1 : outTransitionsTemp) {
                                s = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
                                // 判断el表达式是否成立
                                if (isCondition(ac.getId(), StringUtils.trim(s.toString()), elString)) {
                                    return nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, elString,
                                            processInstanceId);
                                }
                            }
                        }
                    } else if ("userTask".equals(ac.getProperty("type"))) {
                        return ((UserTaskActivityBehavior) ((ActivityImpl) ac).getActivityBehavior()).getTaskDefinition();
                    } else {
                    }
                }
                return null;
            }
            return null;
        }  
    
        /** 
         * 查询流程启动时设置排他网关判断条件信息  
         * @param String gatewayId          排他网关Id信息, 流程启动时设置网关路线判断条件key为网关Id信息  
         * @param String processInstanceId  流程实例Id信息  
         * @return 
         */  
        public String getGatewayCondition(String gatewayId, String processInstanceId) {  
            Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();
            Object object= runtimeService.getVariable(execution.getId(), gatewayId);
            return object==null? "":object.toString();  
        }  
    
        /** 
         * 根据key和value判断el表达式是否通过信息  
         * @param String key    el表达式key信息  
         * @param String el     el表达式信息  
         * @param String value  el表达式传入值信息  
         * @return 
         */  
        public boolean isCondition(String key, String el, String value) {  
            ExpressionFactory factory = new ExpressionFactoryImpl();    
            SimpleContext context = new SimpleContext();    
            context.setVariable(key, factory.createValueExpression(value, String.class));    
            ValueExpression e = factory.createValueExpression(context, el, boolean.class);    
            return (Boolean) e.getValue(context);  
        }  

    编写测试用例:

    @Test
        public void startProcessInstance(){
            //流程定义的key
            String processDefinitionKey = "exclusiveGateWay";
            Map<String, Object> param = new HashMap<>();
            //${creditor=='group'} 添加流程变量,选定流程路线
            param.put("creditor", "group");
            param.put("subCreditor", "a");
            processEngine.getRuntimeService()
                            .startProcessInstanceByKey(processDefinitionKey,param);
        }

    按照上述的测试用例流程到达-费用报销申请,下一步应该是审批【部门经理】

    @Test
        public void nextTaskInfo() throws Exception{
            ActivitiNextTask task = new ActivitiNextTask();
            String processInstanceId = "387905";
            TaskDefinition nextTaskGroup = task.getNextTaskInfo(processInstanceId);
            System.out.println(nextTaskGroup.getNameExpression().getExpressionText());
        }

    这里写图片描述

    展开全文
  • 异步加载时,只能通过后台判断生成root节点,但是这样一来有一个问题,就是第一次访问界面时, 树的初始化比较慢,大概会有一秒左右的时间,树是空白的,虽然只有一秒左右的时间,但是对于我来说是没有办法容忍的,...
  • activiti获取下一个节点信息

    千次阅读 2018-12-25 19:19:17
    参考网址: ... /** ... * 获取下一个用户任务用户组信息 * @param String taskId 任务Id信息 * @return 下一个用户任务用户组信息 * @throws Exception */ public Set&amp;lt...
  • 删除单向链表的最后一个节点

    千次阅读 2020-03-07 20:05:42
    分为三个步骤: 1、找到倒数第二个内存,把它的指针域置为NULL; 2、将最后一个节点所占用的内存(堆内存)释放掉; 第一步:
  • activiti拿取 当前任务的下一个节点

    千次阅读 2017-06-12 17:11:59
    在实际的工作流业务开发中, 当用户完成当前用户任务时, 需要指定下一个用户任务的审核人。此时我们需要获取下一个节点的一些...如果下一个节点为网关我们需要判断流程线路。     Java代码  /** 
  • 二叉树的下一个节点(java版)

    千次阅读 2017-06-06 15:53:06
    若给定的节点pNode的右子树不为空,则中序遍历的下一个节点为其右子树的最左侧节点。 //2.若给定的节点pNode的右子树为空,分两种情况。一种是左子树不为空,此时中序遍历的下一个节点为其父节点。另一种情况是,其...
  • if(node instanceof Element){////判断个节点属于Element ,再进行取值 System.out.println("子节点名称为:"+node.getNodeName()+" "+"对应的值为:"+node.getFirstChild().getNodeValue()); } } ...
  • C#判断节点下是否还有子节点的方法

    千次阅读 2018-02-08 11:43:03
    自己稍微有点修正、整理,望原作者见谅,谢谢。...理论上来说 C# 的 XmlNode 类提供的 ChildNodes 以及 HasChildNodes 属性可以判断是否存在子节点。 但是在有 InnerText 的情况下,无论是 ChildNodes....
  • activiti,根据流程实例id,获取下userTask节点的配置信息,需要在每个节点都添加complete的监听器   public class Competeistener implements TaskListener {  private ProcessEngine processEngine = ...
  • 单向链表在O(1)时间内删除一个节点

    千次阅读 2016-06-05 12:36:23
    单向链表在O(1)时间内删除一个节点
  • 将完全二叉树每个节点的next指针赋值,每个节点的next指针指向同一层的下一个节点,要求空间复杂度是O(1) 其实如果没有空间复杂度的要求,可以使用层次遍历,一种是使用队列,为了控制层次可以在每层的节点
  • 某RAC数据库一个节点“宕机”原因分析 (RAC down机原因分析)
  • 此时可以分别从两个节点开始,沿着parent指针走向根节点,得到两个链表,然后求两个链表的第一个公共节点,这个方法很简单,不需要详细解释的。 情况二:节点只有左、右指针,没有parent指针,root已知 思路:有...
  • 当el-tree 从后台拿到数据动态展示出来时,会出现一个节点下面的所有子节点全部被勾选了 解决方法代码如下: <el-tree :data="data" show-checkbox node-key="id" ref="tree" :check-strictly="isCheck" ...
  • jstree 判断是否是根节点

    千次阅读 2011-12-23 12:01:15
    .bind('select_node.jstree', function (event, data) { if ($(data.rslt.obj).attr('rel') == 'root') {  $(".helpinfo").show();  }  else {  $(".helpinfo").hide();...
  • spark集群其中一个节点没有启动成功

    千次阅读 2014-07-19 17:23:51
    Spark Command: /usr/java/jdk1.7/bin/java -cp ::/home/hadoop2/spark/spark-1.0.0/conf:/home/hadoop2/spark/spark-1.0.0/assembly/target/scala-2.10/spark-...有的时候只有一个worker。貌似也没有什么规律。
  • 如何判断是否存在公共节点,并找出它们的第一个公共结点。 思想: 1. 如果两个链表相交,则从相交点开始,后面的节点都相同,即最后一个节点肯定相同; 2. 从头到尾遍历两个链表,并记录链表长度,当二者的...
  • 题目描述:单链表可能有... 的第一个节点;如果不相交,返回 null 即可。 首先,感谢程云老师的分享!以下是本问题的解决方法整理。 思路:  链表分有环链表和无环链表,如果两个链表存在相交,则只有两种可能,两
  • 在审批该节点之前,查询该节点的下级审批节点的信息。 直接上代码: public FlowElement getNextUserFlowElement(String processInstanceId){ Task task=taskService.createTaskQuery().processInstanceId...
  • 很流行的一个问题,常见于各种面试中,http://fayaa.com/tiku/view/16/这里有一个很好的汇总. 找寻二叉树中两个节点的公共父节点中最近的那个节点 情况1. 节点只有left/right,没有parent指针,root已知 情况2....
  • 问题描述:给定两个单向链表,找出它们的第一个公共节点
  • LintCode 删除链表中倒数第n个节点

    千次阅读 2016-03-31 18:58:06
    题目相当于在“返回链表倒数第n个节点”的基础上增加功能,通过上篇文章,我们已经有了寻找倒数第n个节点的方法。这里我们只提供遍历次的方法,遍历2次也是这道理。 删除的关键在于要找
  • 给定一个链表和一个特定值x,对链表进行分隔,使得所有小于x的节点都在大于或等于x的节点之前。 你应当保留两个分区中每个节点的初始相对位置。 示例: 输入: head = 1->4->3->2->5->2, x = 3 ...
  • 之前已在台服务器上部署了elasticsearch,今天想着尝试elasticsearch的分布式,但受限于硬件资源(手头上只有一台服务器),所以就想着在台服务器上部署多结点(下文以2结点作为例子)。   1、首先将已...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 305,397
精华内容 122,158
关键字:

如何判断只有一个节点