Java 查找多个列表中的元素数并合并;是否删除if/else复合体?
我有一份清单:Java 查找多个列表中的元素数并合并;是否删除if/else复合体?,java,list,Java,List,我有一份清单: List<List<String>> someList = new List<List<>>(); 我正试图设计一种方法,通过组合上面的一些嵌套列表来创建一个特定大小(1-5个元素)的新列表。我可以做如下操作(在本例中,有三个元素): getThree()方法正在创建一个由someList子列表中的元素组成的新列表。它不能拆分子列表(即,它不能从包含2个元素的子列表中提取1个元素),它正在合并整个子列表。因为您声明组合列表的优先级
List<List<String>> someList = new List<List<>>();
我正试图设计一种方法,通过组合上面的一些嵌套列表来创建一个特定大小(1-5个元素)的新列表。我可以做如下操作(在本例中,有三个元素):
getThree()
方法正在创建一个由someList
子列表中的元素组成的新列表。它不能拆分子列表(即,它不能从包含2个元素的子列表中提取1个元素),它正在合并整个子列表。因为您声明组合列表的优先级是从左到右。O(N^2)循环足以处理组合子列表小于或等于所需数量的情况
public static void main(String[] args) throws Exception {
List<List<String>> someList = new ArrayList() {{
add(new ArrayList() {{
add("a1");
add("a2");
}});
add(new ArrayList() {{
add("b1");
}});
add(new ArrayList() {{
add("c1");
add("c2");
add("c3");
}});
add(new ArrayList() {{
add("d1");
}});
}};
combine(someList, 4);
for(List<String> subList : someList) {
System.out.println(subList);
}
}
private static void combine(List<List<String>> someList, int combineAmount) {
for (int i = 0; i < someList.size(); i++) {
// Check if the current list already equals or exceeds the combineAmount
if (someList.get(i).size() >= combineAmount) {
continue;
}
// Add sublists to the current sublists until the size of the current
// sublist equals or exceeds the combineAmount
for (int j = i + 1; j < someList.size(); j++) {
if (someList.get(i).size() + someList.get(j).size() > combineAmount) {
continue;
}
someList.get(i).addAll(someList.get(j));
someList.remove(j);
j--;
// Don't bother checking other sublists if the newly
// combined sublists equals or exceeds the combineAmount
if (someList.get(i).size() >= combineAmount) {
break;
}
}
}
}
结果(组合计数=2):
结果(组合计数=6):
如果您打算从连续列表中继续收集,直到获得5个元素,请继续添加,然后在列表已满时中断:
public static List<String> fill(List<List<String>> sources, int size) {
List<String> list = new ArrayList<>();
for (List<String> source : sources)
if (source.size() <= size - list.size())
list.addAll(source);
return list;
}
在java 8中,非常简洁:
public static List<String> fill(List<List<String>> sources, int size) {
return sources.stream().reduce(new ArrayList<>(),
(a, b) -> {if (b.size() <= a.size() - size) a.addAll(b); return a;});
}
公共静态列表填充(列表源,整数大小){
返回sources.stream().reduce(新的ArrayList(),
(a,b)->{if(b.size()b.size()-a.size())
.reduce(新的ArrayList(),(a,b)->
{if(b.size()据我所知,您希望将列表列表合并为总共5个索引。执行此操作时,您希望它首先对左侧进行优先级排序
以下是我创建的一个方法。我知道您不想要一个具体的示例,但我认为示例将帮助您理解并帮助其他也有此问题的人:
private static List<String> getListOf(List<List<String>> someList, int size) {
List<List<String>> combine = new ArrayList<List<String>>();
List<List<String>> combinePrev = new ArrayList<List<String>>();
int value = 0;
int indexCloseValue = 0;
int indexClose;
for(int i = 0; i < someList.size(); i++){//Loops through the lists
value = someList.get(i).size();
boolean[] indexAdded = new boolean[someList.size()];//Used to make sure to not add duplicates
indexAdded[i] = true;
combine.add(someList.get(i));//add current loop to the combine list.
do{//A loop to try to add values other than the one of index i to equal size. This loops multiple times because it may take more than two to equal size.
indexCloseValue = 0;
indexClose = -1;
for(int j = 0; j < someList.size(); j++){
if(!indexAdded[j]){
int listSize = someList.get(j).size();
if(value + listSize > indexCloseValue && value + listSize <= size){
indexCloseValue = listSize;
indexClose = j;
}
}
}
if(indexClose == -1){
break;
}else{
combine.add(someList.get(indexClose));
value+=indexCloseValue;
indexAdded[indexClose] = true;
}
}while(value + indexCloseValue < size);
int added = 0;
for(List<String> str : combine){//Check size of combine list
added+=str.size();
}
int addedPrev = 0;
for(List<String> str : combinePrev){//Check size of combinePrev list
addedPrev+=str.size();
}
if(added > addedPrev && added <= size){
combinePrev = new ArrayList<List<String>>(combine);//Set combinePrev to combine if it is larger but less than size
}
combine = new ArrayList<List<String>>();//Reset combine
}
List<String> returnList = new ArrayList<String>();
for(List<String> list : combinePrev){//converts double list to a single list of strings at length "size".
for(String str : list){
returnList.add(str);
}
}
return returnList;
}
private静态列表getListOf(List someList,int size){
List combine=new ArrayList();
List combinePrev=new ArrayList();
int值=0;
int indexCloseValue=0;
int indexClose;
for(int i=0;i 如果(value+listSize>indexCloseValue&&value+listSize addedPrev&&added)您是否正在尝试将列表列表转换为单个列表?我理解正确吗?我必须走大约一个小时,如果这个问题没有得到回答,那么我想我有一个答案给您。组合哪些列表以及项目的顺序是否重要?Sa如果您有大小为{1,3,2,4,1}
的myList
,并且您想要一个大小为size=5
的结果列表,那么以下所有组合都被认为是解决方案吗?{1+3+1}
,{3+2}
,{4+1}
@Kobit,可以组合任意数量的列表,但最左边的列表优先。在您的示例中,它将是{1+3+1}
。类似于“如果它可以使用子列表1,就使用它;如果它不能使用子列表2,就使用它;…”。是不是你想继续从连续列表中添加元素,直到你有5个?@Shar1er80我没有注意到。事实上,考虑到这一点,代码变得简单多了。你认为编辑后的代码符合OP现在的要求吗?我更喜欢你的解决方案,因为我认为我更了解OP的意图。我只是不明白它的目的每次调用都返回相同的结果。我认为合并是永久性的,而不是临时性的,因为您可能会遇到这样的情况,即您永远不会看到子列表是返回结果的一部分。例如,在OP的示例列表{4,1,3,1}中,每次调用潜在的getOne()将始终导致索引1处的子列表,而索引3处的子列表将永远不会返回。
[a1, a2, b1, d1]
[c1, c2, c3]
[a1, a2]
[b1, d1]
[c1, c2, c3]
[a1, a2, b1, c1, c2, c3]
[d1]
public static List<String> fill(List<List<String>> sources, int size) {
List<String> list = new ArrayList<>();
for (List<String> source : sources)
if (source.size() <= size - list.size())
list.addAll(source);
return list;
}
Collections.sort(sources, (a, b) -> b.size() - a.size());
public static List<String> fill(List<List<String>> sources, int size) {
return sources.stream().reduce(new ArrayList<>(),
(a, b) -> {if (b.size() <= a.size() - size) a.addAll(b); return a;});
}
public static List<String> fill(List<List<String>> sources, int size) {
return sources.stream()
.sorted((a,b) -> b.size() - a.size())
.reduce(new ArrayList<>(), (a, b) ->
{if (b.size() <= a.size() - size) a.addAll(b); return a;});
}
private static List<String> getListOf(List<List<String>> someList, int size) {
List<List<String>> combine = new ArrayList<List<String>>();
List<List<String>> combinePrev = new ArrayList<List<String>>();
int value = 0;
int indexCloseValue = 0;
int indexClose;
for(int i = 0; i < someList.size(); i++){//Loops through the lists
value = someList.get(i).size();
boolean[] indexAdded = new boolean[someList.size()];//Used to make sure to not add duplicates
indexAdded[i] = true;
combine.add(someList.get(i));//add current loop to the combine list.
do{//A loop to try to add values other than the one of index i to equal size. This loops multiple times because it may take more than two to equal size.
indexCloseValue = 0;
indexClose = -1;
for(int j = 0; j < someList.size(); j++){
if(!indexAdded[j]){
int listSize = someList.get(j).size();
if(value + listSize > indexCloseValue && value + listSize <= size){
indexCloseValue = listSize;
indexClose = j;
}
}
}
if(indexClose == -1){
break;
}else{
combine.add(someList.get(indexClose));
value+=indexCloseValue;
indexAdded[indexClose] = true;
}
}while(value + indexCloseValue < size);
int added = 0;
for(List<String> str : combine){//Check size of combine list
added+=str.size();
}
int addedPrev = 0;
for(List<String> str : combinePrev){//Check size of combinePrev list
addedPrev+=str.size();
}
if(added > addedPrev && added <= size){
combinePrev = new ArrayList<List<String>>(combine);//Set combinePrev to combine if it is larger but less than size
}
combine = new ArrayList<List<String>>();//Reset combine
}
List<String> returnList = new ArrayList<String>();
for(List<String> list : combinePrev){//converts double list to a single list of strings at length "size".
for(String str : list){
returnList.add(str);
}
}
return returnList;
}