查找多个列表中的元素数量并组合; 删除if/else复杂?

gat*_*tor 8 java list

我有一份清单清单:

List<List<String>> someList = new List<List<>>();
Run Code Online (Sandbox Code Playgroud)

列表的最大大小为五个字符串.它如下所示:

someList.get(0).size(); // 4 elements
someList.get(1).size(); // 1 elements
someList.get(2).size(); // 3 elements
someList.get(3).size(); // 1 elements
...
Run Code Online (Sandbox Code Playgroud)

我正在尝试通过组合上面的一些嵌套列表来设计一种方法来创建一个特定大小的新列表(1-5个元素).我可以做类似下面的事情(在这个例子中,三个元素):

public List<String> getThree() {
    for (int j = 0; j < someList.size(); j++) {
        //look for nested lists of size 3
        if (someList.get(j).size() == 3) {
            return someList.get(j);
        }
    for (int j = 0; j < someList.size(); j++) {
        //if found nested list of size 2, find one of size 1 to combine
        if (someList.get(j).size() == 2) {
            for (int k = 0; k < someList.size(); k++) {
                if (someList.get(k).size() == 1) {
                    return someList.get(j).add(someList.get(k).get(0));
                }
            }
        }
    for (int j = 0; j < someList.size(); j++) {
        //if found nested list of size 1, find one of size 2 to combine
        if (someList.get(j).size() == 1) {
            for (int l = 0; l < someList.size(); l++) {
                if (someList.get(l).size() == 2) {
                    return someList.get(j).addAll(someList.get(l));
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有包含循环,如果没有大小为2的子列表,找到三个大小为1,但你可以想象它可以获得多长时间和多么丑陋.顺序很重要,因此for循环顺序递增(即,我宁愿将subList 1 + 2多于2 + 3,1 + 3多于2 + 3等).

我希望找到一种动态实现它的方法.我只能理解这种getFive方法是多么难以理解,而且这种方法将提供给我目前的方法.我有多个方法(getOne通过getFive),在这个意义上它不需要是动态的,我只想摆脱很多if/else和for循环来降低复杂性并提高可读性.

我应该提一下这是与家庭作业有关的,所以我不太想要一个具体的答案,而是一个正确方向的推动.东西modulo吧?与剩余的人一起做?

编辑; 澄清并举例说明:

aList = new List<String>;
aList.add("a");
aList.add("b");
someList.add(aList);
bList = new List<String>;
bList.add("c");
someList.add(bList);
newList = someList.getThree();
//newList.size() == 3
//newList contains "a","b","c"
Run Code Online (Sandbox Code Playgroud)

getThree()方法创建一个新列表,其中包含来自子列表的元素someList.它不能拆分子列表(即,它不能从2个元素的子列表中取出1个元素),它将整个子列表组合在一起.

Boh*_*ian 3

如果您的目的是继续从连续的列表中收集直到获得 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;
}
Run Code Online (Sandbox Code Playgroud)

如果您想首先使用最大的列表,请添加以下行作为该方法的第一行:

Collections.sort(sources, (a, b) -> b.size() - a.size());
Run Code Online (Sandbox Code Playgroud)

在 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;});
}
Run Code Online (Sandbox Code Playgroud)

并使用最大优先模式:

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;});
}
Run Code Online (Sandbox Code Playgroud)