package ceshi.About8;
import java.util.*;
import java.util.stream.Collectors;
public class LamdaTest {
private static String getA(){return "a";}
public static void main(String[] args) {
List<NodeTest> nodeTests = Arrays.asList(
new NodeTest("A",2.11,true),
new NodeTest("B",2.00,true),
new NodeTest("G",2.11,false),
new NodeTest("G",1.10,false),
new NodeTest("C",2.10,true),
new NodeTest("D",2.10,true),
new NodeTest("E",2.10,false),
new NodeTest("F",2.10,false)
);
// 30選15中的15
int selection = 6;
long start1 = System.currentTimeMillis();
ArrayList<List<NodeTest>> result1 = getResultList(nodeTests,selection);
long end1 = System.currentTimeMillis();
System.out.println("1所用時間爲:" +(end1 - start1));
}
/**
* 獲取幾選幾的所有集合
*
* @param nodeTests 集合
* @selection 策略 幾選幾
*/
public static ArrayList<List<NodeTest>> getResultList (List<NodeTest> nodeTests,int selection){
//獲取標識爲false的組合
List<NodeTest> allFasleCol = nodeTests.stream().filter((x)->x.getFlag()==false).collect(Collectors.toList());
//獲取標識爲true的組合
List<NodeTest> allTrueCol = nodeTests.stream().filter((x)->x.getFlag()==true).collect(Collectors.toList());
//爲false的必須有幾個
int selectionFlase = selection - allTrueCol.size();
ArrayList<List<NodeTest>> allChildrenFasleCol = getFalseAllChildren(allFasleCol,selectionFlase);
ArrayList<List<NodeTest>> result = new ArrayList<>();
for(List<NodeTest> nodesList :allChildrenFasleCol){
nodesList.addAll(allTrueCol);
result.add(nodesList);
System.out.println("子集:"+nodesList);
}
return result;
}
/**
* 獲取子集個數爲selection所有集合,去重
*
* @param nodesLlist 集合
* @param selection 子集中的個數
*/
public static ArrayList<List<NodeTest>> getFalseAllChildren(List<NodeTest> nodesLlist,int selection){
ArrayList<List<NodeTest>> result = new ArrayList<>();
for (int i = (1<<selection-1); i < Math.pow(2, nodesLlist.size()); i++) { // 遍歷元素>=selection個數的子集合的情況。(注:不是所有的,大於selection,但是是2的倍數的沒有也在了裏面)
List<NodeTest> list = new ArrayList<>();
int index = i; // 爲了計算每個位置上是否有元素
for (int j = 0; j < nodesLlist.size(); j++) { //遍歷集合所有數字如果有則添加到集合,沒有則向右位移
if((index & 1)==1){ //index和1做按位與的操作, 如果等於1說明位置上有元素,如果不等於1說明位置上沒有元素。
list.add(nodesLlist.get(j)); //添加到集合中
}
index >>= 1;//右移一位,進入下一次循環,用來判斷左邊一位是否是1
}
// 去重並且符合selection的子集添加到集合中
if(list!=null && list.size()>0 && list.stream().map(NodeTest::getId).collect(Collectors.toSet()).size()==list.size()&&list.size()==selection){
result.add(list); //都添加到大集合中,進行去重
}
}
return result;
}
}
package ceshi.About8;
public class NodeTest {
public String id;
public Double value;
public boolean flag;
public NodeTest(String id,double value,boolean flag){
this.id = id;
this.value = value;
this.flag = flag;
}
public boolean getFlag() {
return flag;
}
public String getId() {
return id;
}
@Override
public String toString() {
return "{" +
"id='" + id + '\'' +
", value=" + value +
", flag=" + flag +
'}';
}
}
總結:短短的幾行代碼是通過自己不斷的優化它才完成的。看着它很開心,知道別人在項目中用它,更開心。