Dieses versuchen:
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());
}
Der Schlüssel ist, dass ein BitSet
stream()
Verfahren darauf hat, die einen Strom von Indizes der one-Bits zurückgibt. Dies kann verwendet werden, um true
Werte in boolean[]
zu setzen. Beachten Sie auch, dass (wie bei Bubletan) ein List<boolean[]>
anstelle von List<Boolean[]>
möglich ist. Das heißt, eine Liste von Arrays von primitiven boolean
Werten anstelle einer Liste von Arrays von boxed Werten. (Dies liegt daran, dass Arrays Referenztypen sind und daher als Typargument verwendet werden können.)
Schließlich, dank Bubletan, deren Lösung ich ergänzt durch Hinzufügen bitSetToArray()
.
UPDATE
srborlongan in einem Kommentar gefragt, ob die folgenden besser sein könnte:
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());
}
es den Vorteil, dass sie weniger dicht hat. Schließlich ist dies nicht Code Golf, APL oder Perl, wo das Ziel zu sein scheint, etwas möglichst knappe zu schreiben.Code, der weniger dicht ist, ist oft, aber nicht immer einfacher zu lesen und zu verstehen.
Es gibt jedoch einige Nuancen in diesem Fall, denke ich. Das von der Stufe mapToObj
ausgegebene "obj" ist long[]
, was als der Parametertyp von BitSet::valueOf
gewertet wird. Dies wirkt sich wiederum auf die Überlastauflösung aus! Es sei denn, Sie sind bereits vertraut mit der BitSet
API, müssen Sie ein bisschen Typ Rückschluss selbst tun, um herauszufinden, was das tut. In diesem Fall ist es besser, einen direkten Methodenaufruf an BitSet.valueOf(long[])
zu haben.
In Bezug auf die Leistung - die nicht immer oberste Priorität hat - denke ich, dass direkte Methodenaufrufe wahrscheinlich besser als eine Kette von map
Operationen durchführen. Das Übergeben eines Werts durch eine zusätzliche Datenstromoperation umfasst möglicherweise zwei Methodenaufrufe und zusätzlich den Overhead des Lambda-Metafactory-Aufrufs für die zusätzlichen Lambda (s). Darüber hinaus werden direkte Methodenaufrufe wahrscheinlich durch das JIT und inlined einfacher als durch das Übergeben von Werten durch den Stream optimiert. Aber ich habe nichts davon verifiziert.
Starten Sie einfach von Null und zählen, einen Integer-Typ als Bitfeld verwendet? – chrylis
Ist das nicht das, was er tut? Konvertieren von int-> binary string und dann char von char zu boolean. – Todd