java 操作樹

1.遞歸查詢根節點的所有子節點id

CREATE DEFINER=`root`@`localhost` PROCEDURE `aaa`(
	IN `areaId` INT
,
	IN `tableName` VARCHAR(50),
	OUT `result` VARCHAR(4000),
	IN `idName` VARCHAR(50),
	IN `parentIdName` VARCHAR(50)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE sTemp VARCHAR(4000);
DECLARE sTempChd VARCHAR(4000);
DECLARE sqlStr VARCHAR(4000);


SET sTemp='';
SET sTempChd = CAST(areaId AS CHAR);
set sqlStr = '';


WHILE sTempChd IS NOT NULL DO
SET sTemp= CONCAT(sTemp,',',sTempChd);


Set @temp = sTempChd;




SET @SQLStr0=concat('SELECT GROUP_CONCAT(',idName,') INTO @temp FROM ',tableName,' WHERE FIND_IN_SET(',parentIdName,',@temp)>0;');




PREPARE sqlStr FROM @SQLStr0;
EXECUTE sqlStr;


Set sTempChd = @temp ;




END WHILE;


Set result = sTemp;


END



areaId:根節點id

idName:id字段名稱

parentIdName:父節點id的字段名稱











2.遞歸獲取某個節點的根節點
	//遞歸獲取某個節點的根節點
	private CategoryTreeNode getRootCategoryNode(List<CategoryTreeNode> trees, Category category,List<Integer> checkLine) {
		CategoryTreeNode categoryTreeNode = null;
		if(trees != null){
			for(CategoryTreeNode node : trees){
				if(null != node){
					//防止死循環
					if(checkLine.contains(node.hashCode())){
						continue;
					}
					
					checkLine.add(node.hashCode());
				}
				
				if(null != node && node.getId()!= null&&
						node.getId().equals(category.getId())){
					categoryTreeNode = node;
					break;
				}
				
				if(node.getChildren() != null && !node.getChildren().isEmpty()){
					CategoryTreeNode tempNode = getRootCategoryNode(node.getChildren(),category,checkLine);
					if(tempNode != null){
						//categoryTreeNode = tempNode;
						categoryTreeNode = node;
						break;
					}
				}
			}
		}
		return categoryTreeNode;
	}
	



3.將list轉換成樹形結構
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
 
import com.sstech.module.content.model.Content;
 
public class ExchangeUtil {
	
	static Logger logger = LoggerFactory.getLogger(ExchangeUtil.class);
	
	public static <T> List<T> iteratorToList(Iterator<T> i){
		List<T> list = new ArrayList<T>();
		if(null == i){
			return list;
		}
		else{
			while(i.hasNext()){
				list.add(i.next());
			}
		}
		
		return list;
	}
	
//	public static <T> Page<T> listToPage(List<T> list){
//		Page<T> result = new Page<T>() {
//			
//		};
//	}
	
	/**
	 * 將list轉換成樹形結構
	 * 
	 * map裏放入
	 * parentIdFieldName : 父節點id字段名
	 * idFieldName : id字段名
	 * childNodeFieldName : 子節點list字段名
	 * 
	 * nodeClass : 節點類路徑
	 * idAndParentIdClass : id字段的類路徑 (默認Integer)
	 * 
	 * @param nodes
	 * @return
	 */
	public static <T> List<T> buildTree(List<T> nodes,Map<String,Object> classParam) throws Exception 
			{
		if(!classParam.containsKey("parentIdFieldName")){
			classParam.put("parentIdFieldName", "parentId");
		}
		if(!classParam.containsKey("idFieldName")){
			classParam.put("idFieldName", "id");
		}
		if(!classParam.containsKey("childNodeFieldName")){
			throw new Exception("leak of childNodeFieldName");
		}
		if(!classParam.containsKey("nodeClass")){
			throw new Exception("leak of nodeClass");
		}
		if(!classParam.containsKey("idAndParentIdClass")){
			throw new Exception("leak of idAndParentIdClass");
		}
 
		List<T> rootNodes = new ArrayList<T>();
		
		List<T> nodesBesidesLeafs = new ArrayList<T>();;
		try {
			nodesBesidesLeafs = buildTreeByList(nodes,classParam);
		} catch (NoSuchMethodException e) {
			logger.error(e.getMessage(),e);
			return new ArrayList<T>();
		} catch (SecurityException e) {
			logger.error(e.getMessage(),e);
			return new ArrayList<T>();
		} catch (NoSuchFieldException e) {
			logger.error(e.getMessage(),e);
			return new ArrayList<T>();
		} catch (IllegalArgumentException e) {
			logger.error(e.getMessage(),e);
			return new ArrayList<T>();
		} catch (IllegalAccessException e) {
			logger.error(e.getMessage(),e);
			return new ArrayList<T>();
		} catch (InvocationTargetException e) {
			logger.error(e.getMessage(),e);
			return new ArrayList<T>();
		}
		if(!nodes.equals(nodesBesidesLeafs)){
			rootNodes = buildTree(nodesBesidesLeafs,classParam);
		}
		else{
			rootNodes = nodesBesidesLeafs;
		}
		
		return rootNodes;
	}
	/**
	 * 獲取除了葉子節點以外的所有節點
	 * 
	 * map裏放入
	 * parentIdFieldName : 父節點id字段名
	 * idFieldName : id字段名
	 * childNodeFieldName : 子節點list字段名
	 * 
	 * nodeClass : 節點類路徑
	 * idAndParentIdClass : id字段的類路徑 (默認Integer)
	 * 
	 * @param nodes
	 * @return
	 */
	static <T> List<T> buildTreeByList(List<T> nodes,Map<String,Object> classParam) 
			throws NoSuchMethodException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException{
		
		List<T> nodesLeafs = new ArrayList<T>();
		List<T> nodesBesidesLeafs = new ArrayList<T>();
 
		String parentIdFieldName = String.valueOf(classParam.get("parentIdFieldName"));
		String idFieldName = String.valueOf(classParam.get("idFieldName"));
		String childNodeFieldName = String.valueOf(classParam.get("childNodeFieldName"));
		
		Class<?> nodeClass = Class.forName(String.valueOf(classParam.get("nodeClass")));
		Class<?> idAndParentIdClass = Class.forName(String.valueOf(classParam.get("idAndParentIdClass")));
		if(null == idAndParentIdClass){
			idAndParentIdClass = Integer.class;
		}
		
		Method equalsMethod = idAndParentIdClass.getMethod("equals",Object.class);
		
		Field parentIdField = null;
		Field idField = null;
		Field childNodeField = null;
		
		do{
			Field[] fildList = nodeClass.getDeclaredFields();
			for(int i=0;i<fildList.length;i++){
				if(fildList[i].getName().equals(parentIdFieldName)){
					parentIdField = fildList[i];
				}
				else if(fildList[i].getName().equals(idFieldName)){
					idField = fildList[i];
				}
				else if(fildList[i].getName().equals(childNodeFieldName)){
					childNodeField = fildList[i];
				}
			}
			nodeClass = nodeClass.getSuperclass();
		}while(!((null != parentIdField && null != idField && null != childNodeField) ||
				nodeClass.getDeclaredFields().length <= 0));
		
		parentIdField.setAccessible(true);
		idField.setAccessible(true);
		childNodeField.setAccessible(true);
 
		if(null == nodes || nodes.isEmpty()){
			return new ArrayList<T>();
		}
		int nodesSize = nodes.size();
		for(int i=0;i<nodesSize;i++){
			boolean hasLeafNodes = false;
			boolean hasFatherNodes = false;
			for(int j=0;j<nodesSize;j++){
 
				if( false == hasLeafNodes && null != parentIdField.get(nodes.get(i)) && null != parentIdField.get(nodes.get(j)) &&
						(Boolean) equalsMethod.invoke(idField.get(nodes.get(i)), parentIdField.get(nodes.get(j))) 
						){
					hasLeafNodes = true;
				}
				
				if( false == hasFatherNodes && null != parentIdField.get(nodes.get(i)) && null != parentIdField.get(nodes.get(j)) &&
						(Boolean) equalsMethod.invoke(parentIdField.get(nodes.get(i)), idField.get(nodes.get(j)))
						){
					hasFatherNodes = true;
					
					Object childNode = childNodeField.get(nodes.get(j));
					if(null == childNode){
						childNode = new ArrayList<T>();
						childNodeField.set(nodes.get(j), childNode);
					}
					
					@SuppressWarnings("unchecked")
					List<T> childNodeList = (List<T>) childNode;
					if(!childNodeList.contains(nodes.get(i))){
						childNodeList.add(nodes.get(i));
					}
				}
 
			}
			
			if(hasFatherNodes && !hasLeafNodes
					&& !nodesLeafs.contains(nodes.get(i))){
				nodesLeafs.add(nodes.get(i));
			}
		}
		
		nodesBesidesLeafs.addAll(nodes);
		nodesBesidesLeafs.removeAll(nodesLeafs);
		return nodesBesidesLeafs;
	}
}






4.獲取樹的某個節點額其子節點id

	@Override
	public IBaseResult deleteById(List<Integer> ids) {
		IBaseResult result = DefaultResult.buildSuccessResult();
		
		
		List<Menu> menuTree =  
				menuMapper.findAll(ConnectionUtil.findServiceMarkBySession(session));
		
		Map<String,Object> classParam = new HashMap<String,Object>();
		classParam.put("childNodeFieldName", "children");
		
		classParam.put("nodeClass", Menu.class.getName());
		classParam.put("idAndParentIdClass", Integer.class.getName());
		
 
		List<Menu> trees =  new ArrayList<Menu>();
		try {
			trees = ExchangeUtil.buildTree(menuTree, classParam);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		
		if(null!=ids){
			for(Integer id : ids){
				List<Integer> treeIds = new ArrayList<Integer>();
				treeIds.add(id);
				getTreeNodeIds(trees,treeIds,new ArrayList<Menu>());
				
				menuMapper.delete(treeIds,ConnectionUtil.findServiceMarkBySession(session));
				
				logger.info(treeIds.toArray().toString());
			}
		}
		
		
		
		return result;
	}
	
	private void getTreeNodeIds(List<Menu> topRootNodes ,List<Integer> result,List<Menu> checkedGroup){
		if(null != topRootNodes){
			for(Menu node : topRootNodes){
				if(result.contains(node.getParentId())){
					result.add(node.getId());
				}
				
				if(null != node.getChildren() && !checkedGroup.containsAll(node.getChildren())){
					checkedGroup.add(node);
					getTreeNodeIds(node.getChildren(),result,checkedGroup);
				}
			}
		}else{
			
		}
		
	}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章