简体   繁体   中英

How to make all variations of list elements using Java streams?

I have a list, for example:

["a", "b", "c"]

and I want to create list of lists that will be variations of elements of this list. Result should be like this:

[["a"], 
 ["b"], 
 ["c"], 
 ["a", "b"], 
 ["a", "c"], 
 ["b", "a"], 
 ["b", "c"], 
 ["c", "a"], 
 ["c", "b"], 
 ["a", "b", "c"], 
 ["a", "c", "b"], 
 ["b", "a", "c"], 
 ["b", "c", "a"], 
 ["c", "a", "b"], 
 ["c", "b", "a"]]

The best (but not necessary) if the solution would be using java streams.

I was trying something like this:

List<List<String>> lists = IntStream.rangeClosed(1, list.size()) //size of sublist
.flatMap(i -> list.subList(0, i).stream()).collect(Collectors.toList())

but it's not working.

What you need to do is make use of k-permutation. You need to perform this k-permutation for every length of the array you are passing to get all possible variations.

Code :

private static List<List<String>> getAllVariations(List<String> elements){
    return IntStream.rangeClosed(1, elements.size()).boxed()
            .flatMap(i-> kPermutate(elements,0,i).stream())
            .collect(Collectors.toList());
}

private static List<List<String>> kPermutate(List<String> allElements, int i, int numberOfElements)
{
    if(i == numberOfElements)
    {
        //New ArrayList because we want a clone of the sublist
        return Arrays.asList(new ArrayList<>(allElements.subList(0, numberOfElements)));
    }
    List<List<String>> tempResult = new ArrayList<>();

    for(int j=i; j<allElements.size(); j++)
    {
        Collections.swap(allElements, i, j);
        tempResult.addAll(kPermutate(allElements, i+1, numberOfElements));
        Collections.swap(allElements, i, j);
    }
    return tempResult;
}

Test:

public static void main(String[] args) {
    List<String> elements = Arrays.asList("a", "b", "c");

    List<List<String>> result = getAllVariations(elements);

    System.out.println(result);
}

Output:

[[a], [b], [c], [a, b], [a, c], [b, a], [b, c], [c, b], [c, a], [a, b, c], [a, c, b], [b, a, c], [b, c, a], [c, b, a], [c, a, b]]

If you don't want to use streams in the getAllVariations method, you could also implement it as a regular for loop like this

private static List<List<String>> getAllVariations(List<String> elements){
    List<List<String>> result = new ArrayList<>();
    //Start from 1 because we don't want to include [] in the list.
    //i<=elements.size(): we use <= because we want the max number of permutations. this is not a 0 based index for that
    for(int i=1;i<=elements.size();i++){
        result.addAll(kPermutate(elements,0,i));
    }
    return result;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM