Попробуйте это:
boolean[] bitSetToArray(BitSet bs, int width) {
boolean[] result = new boolean[width]; // all false
bs.stream().forEach(i -> result[i] = true);
return result;
}
List<boolean[]> bool(int n) {
return IntStream.range(0, (int)Math.pow(2, n))
.mapToObj(i -> bitSetToArray(BitSet.valueOf(new long[] { i }), n))
.collect(toList());
}
Ключ в том, что BitSet
имеет stream()
метод на нем, который возвращает поток индексов один бит. Это можно использовать для установки значений true
в boolean[]
. Также обратите внимание, что (например, Bubletan) можно использовать List<boolean[]>
вместо List<Boolean[]>
. То есть, список массива примитивных значений boolean
вместо списка массива значений в коробке Boolean
. (Это связано с тем, что массивы имеют ссылочные типы и поэтому могут использоваться как аргумент типа.)
Наконец, благодаря Bubletan, решение которого я добавил, добавив bitSetToArray()
.
UPDATE
srborlongan спросил в комментариях, может ли следующий будет лучше:
List<boolean[]> bool(int n) {
return IntStream.range(0, (int)Math.pow(2, n))
.mapToObj(i -> new long[] { i })
.map(BitSet::valueOf)
.map(bs -> bitSetToArray(bs, n))
.collect(toList());
}
Это имеет преимущество быть менее плотным. В конце концов, это не код golf, APL или Perl, где цель, похоже, состоит в том, чтобы написать что-то самое краткое.Кодекс, который является менее плотным, часто, но не всегда, легче читать и понимать.
Есть некоторые нюансы в этом случае, хотя, я думаю. «Obj», испускаемый этапом mapToObj
, равен long[]
, который определяется как тип параметра BitSet::valueOf
. Это, в свою очередь, влияет на разрешение перегрузки! Если вы уже не знакомы с API BitSet
, вы должны сами сделать вывод о том, что это такое. Поэтому в этом случае лучше иметь прямой вызов метода BitSet.valueOf(long[])
.
С точки зрения производительности, которая не всегда является главным приоритетом, я думаю, что прямые вызовы методов, вероятно, работают лучше, чем цепочки из map
операций. Передача значения через дополнительную операцию потока включает в себя, возможно, два вызова метода, плюс накладные расходы Lambda Metafactory требуют дополнительных лямбда (-ов). Кроме того, прямые вызовы методов, скорее всего, легче оптимизируются JIT и встроены, чем передача значений через поток. Но я ничего не проверял.
Просто начать с нуля и подсчитывают, используя целочисленный тип, как битовое поле? – chrylis
Разве это не то, что он делает? Преобразование int-> двоичной строки, а затем char с помощью char для boolean. – Todd