import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.stream.*;

// The main method must be in a class named "Main".
class Main {
    public static void main(String[] args) {
        var tests = List.of(new Object[]{2, "and", "or"}, new Object[]{2, "or", "and"}, new Object[]{2, "and", "and"},
                new Object[]{3, "and", "or"}, new Object[]{3, "or", "and"}, new Object[]{3, "or", "or"},
                new Object[]{4, "and", "or"}, new Object[]{4, "or", "and"}, new Object[]{4, "and", "and"});


        var list = List.of("str1", "str2", "str3", "str4", "str5", "str6", "str7", "str8", "str9", "str10", "str11");

        tests.forEach(test -> {
            System.out.println(String.format("%nInner elements: %s - Inner divider: %s - Outer divider: %s", test[0], test[1], test[2]));
            for (int i = 1; i <= list.size(); i++) {
                System.out.println(buildPairs(list.subList(0, i), (String) test[1], (String) test[2], (Integer) test[0]));
            }
        });
    }

    public static String buildPairs(List<String> list, String innerDivider, String outerDivider, int innerSize) {
        var partitions = IntStream.iterate(0, i -> i < list.size(), i -> i + innerSize)
                .mapToObj(i -> list.subList(i, Math.min(i + innerSize, list.size())))
                .toList();

        var paris = partitions.stream()
                .map(partition -> joinPairs(partition, 2, innerDivider, innerDivider, 0))
                .flatMap(List::stream)
                .toList();

        return joinPairs(paris, 1, outerDivider, outerDivider, 0).get(0);
    }
    
    public static List<String> joinPairs(List<String> list, int pairsLimit, String innerDivider, String outerDivider, int iteration) {
        if (list == null || list.isEmpty()) return new ArrayList<>();
        
        var pairs = new ArrayList<String>();

        for (int i = 0; i <= list.size(); i += 2) {
            if (i + 1 < list.size()) {
                var divider = innerDivider;
                if (i == 0 && iteration > 0) divider = outerDivider;

                if (pairs.size() < pairsLimit) {
                    var pair = "(" + list.get(i) + " " + divider + " " + list.get(i + 1) + ")";
                    pairs.add(pair);
                } else {
                    iteration++;
                    pairs.addAll(list.subList(i, list.size()));
                    return joinPairs(pairs, pairsLimit, innerDivider, outerDivider, iteration);
                }
            } else {
                if (i < list.size()) pairs.add(list.get(i));
                if (pairs.size() > 1) {
                    iteration++;
                    return joinPairs(pairs, pairsLimit, innerDivider, outerDivider, iteration);
                }
            }
        }
        return pairs;
    }
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: