Поток Java, уменьшающий количество списков по условию

#java #list #java-8 #java-stream #reduce

#java #Список #java-8 #java-stream #уменьшить

Вопрос:

На Java 1.8 или выше возможно ли сокращение списка list?

Мне нужны массивы чисел, когда сумма чисел не может превышать 8.

Пример: у меня есть следующий список: [2, 4, 6]. Возврат может быть [ [ 2 , 4 ] , [ 6 ] ] или [ [ 2, 6 ],[ 4 ] ].

Я попробовал следующий способ:

 List<Integer> nums = Arrays.asList(2,4,6);
        nums.stream()
            .filter((p) -> p <= 8)
            .map(Collections::singleton)
            .reduce(new ArrayList<List<Integer>>(), (s1, s2) -> {
                int sumS1 = s1.stream().reduce(0, (n1, n2) -> n1   n2);
                if (sumS1 == 8 ) return s1;
                int sumS2 = s1.stream().reduce(0, (n1, n2) -> n1   n2);
                if (sumS1   sumS2 <= 8 ) return s1.addAll(s2);
                return s1;
            })
            .collect(Collectors.toSet());
  

Но я не получил ожидаемого результата.

Я использовал stateful и доступ к внешним переменным control, но это не лучший способ.

Есть ли способ создать это с помощью Stream и без состояния?

Я думаю, что это противоположно flatMap

Комментарии:

1. Java Streams — неподходящий инструмент для этого. Проблема, вероятно, должна быть реализована с помощью рекурсии .

Ответ №1:

Если вы хотите найти комбинацию, которая удовлетворяет условиям, из всех комбинаций.

 List<Integer> list = Arrays.asList(2, 4, 6);
List<List<Integer>> result = IntStream.range(0, 1 << list.size())
    .mapToObj(i -> IntStream.range(0, list.size())
        .filter(j -> (1 << j amp; i) != 0)
        .mapToObj(list::get)
        .collect(Collectors.toList()))
    .filter(x -> x.stream().mapToInt(i -> i).sum() < 8)
    .collect(Collectors.toList());
System.out.println(result);
  

вывод

 [[], [2], [4], [2, 4], [6]]