注:这个问题是在一次面试的时候遇到的,当时还以为就是简单的maven打包设置,然后面试官说是要设计一个类似maven能自动设别的编译系统。这里说下思路及实现过程。
首先,这个问题说简单也简单,说复杂也复杂;简单的说,那就是直接让客户把这种依赖关系定义好,那我们就不用那么辛苦了,当然这是理想的状态,实际上很多客户很"懒"的,他可能只告诉你哪两个项目之间有依赖关系,他不可能把所有依赖关系链都告诉你:A依赖B,B依赖C,A依赖D,D依赖F。。。。但是需要你通过算法来计算出来得到诸如:A-B-C、A-D-F的依赖链,而且还要保证你得到的依赖链不得有重复情况。
好了,话不多说,直接看代码把:
package com.cn.lizihao.compileTool; import java.util.*; public class CompileTools2 { //模拟数据,假设现在知道单个依赖、两两依赖,实际我们会有项目名称,根据项目名称的两两或者单一依赖进行检索、配对、组合 public static List<List<String>> getDatas(){ List<List<String>> datas = new ArrayList<>(); List<String> a = new ArrayList<>(Arrays.asList(new String[]{"a","b"})); List<String> b = new ArrayList<>(Arrays.asList(new String[]{"b","c"})); List<String> c = new ArrayList<>(Arrays.asList(new String[]{"e","g"})); List<String> d = new ArrayList<>(Arrays.asList(new String[]{"a","c"})); List<String> e = new ArrayList<>(Arrays.asList(new String[]{"e","b"})); List<String> f = new ArrayList<>(Arrays.asList(new String[]{"b","g"})); List<String> g = new ArrayList<>(Arrays.asList(new String[]{"c","d"})); datas.add(a); datas.add(b); datas.add(c); datas.add(d); datas.add(e); datas.add(f); datas.add(g); return datas; } //采用集合保存依赖关系 采用冒泡法+递归重复计算、组合集合 public static void reSetDatas(List<List<String>> datas,List<List<String>> finalList,int count){ List<List<String>> compareList = finalList; if(finalList == null || finalList.size()==0){//如果是第一次,则集合自己比较 compareList.addAll(datas); } for(int i=0;i<datas.size() && count < datas.size();i++){ List<String> a = datas.get(i); //获取首末元素 String s1 = a.get(0); String s2 = a.get(a.size() - 1); if (convertData(finalList,a)) continue; for(int j = 0;j < compareList.size();j++){ List<String> convertList = new ArrayList<>(); List<String> b = compareList.get(j); if (convertData(finalList,b)) continue; //获取首末元素 String s3 = b.get(0); String s4 = b.get(b.size() - 1); if(s1.equals(s4) && !s2.equals(s3)){ convertList.addAll(b); convertList.addAll(a); finalList.add(distinctList(convertList)); } if(s2.equals(s3) && !s1.equals(s4)){ convertList.addAll(a); convertList.addAll(b); finalList.add(distinctList(convertList)); } } count++; reSetDatas(datas,finalList,count); } }
//当集合中只有一个元素且不存在依赖关系并且未添加过时,进行添加 private static boolean convertData(List<List<String>> finalList,List<String> a) { if (a == null || a.size() <= 0) return true; if (a.size() == 1) { if (!finalList.contains(a)) finalList.add(a); return true; } return false; } //对最终组合完成的集合进行去重、过滤包含链接 public static List<List<String>> filterList(List<List<String>> list){ if(list == null || list.size() == 0) return null; List<List<String>> result = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { List<String> list1 = list.get(i); boolean a = true; for (int j = i+1; j < list.size() && a; j++) { List<String> list2 = list.get(j); boolean isContain = compareList(list1, list2); if(isContain){ a = false; list.remove(i); i--;//注:这里因为将下标去除了,指针后移,所以需要做--操作 continue; } } if(a) result.add(list1); } return result; } //比较两个集合中元素如果存在包含关系则返回true,否则false public static boolean compareList(List<String> list1,List<String> list2){ if(list1==null || list1.size()==0 || list2 ==null || list2.size()==0) return true; boolean result = true; for (int i = 0; i <list1.size() ; i++) { if(!list2.contains(list1.get(i))) result = false; } return result; } //对单个集合去重 public static List<String> distinctList(List<String> list){ if(list == null || list.size()==0) return null; List<String> newList = new ArrayList<>(); for (int i = 0; i <list.size() ; i++) { if(!newList.contains(list.get(i))) newList.add(list.get(i)); } return newList; } public static void main(String[] args) { List<List<String>> datas = getDatas(); System.out.println(datas); List<List<String>> finalList = new ArrayList<>(); int count = 0; reSetDatas(datas,finalList,count); // System.out.println(finalList); List<List<String>> lists = filterList(finalList); System.out.println(lists); } }