use*_*315 11 java java-8 java-stream
在给定所需布尔值的最大数量的情况下,生成可能的布尔组合的最优雅方法是什么?
例如:
bool(1) -> [false], [true]
bool(2) -> [false, false], [false, true], [true, false], [true, true]
...
Run Code Online (Sandbox Code Playgroud)
这是我目前的实施:
public static List<Boolean[]> bool(int n) {
return IntStream.range(0, (int) Math.pow(2, n))
.mapToObj(i -> StringUtils.leftPad(Integer.toBinaryString(i), n, '0').chars().mapToObj(c -> c != '0').toArray(Boolean[]::new))
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
但是我不满意我使用整数,然后映射到二进制,StringUtils.leftPad并map返回一个Boolean[]而不是一个boolean[].
使用Stream API在单线程中有更好的方法吗?
试试这个:
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());
}
Run Code Online (Sandbox Code Playgroud)
关键是它BitSet有一个stream()方法,它返回一位索引流.这可用于将true值设置为a 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());
}
Run Code Online (Sandbox Code Playgroud)
它确实具有密度较低的优点.毕竟,这不是代码高尔夫,APL或Perl,其目标似乎是尽可能以最简洁的方式编写代码.密度较低的代码通常(但并非总是)更容易阅读和理解.
我认为,在这种情况下有一些细微差别.mapToObj舞台发出的"obj"被long[]推断为参数类型BitSet::valueOf.这又会影响重载分辨率!除非你已经非常熟悉BitSetAPI,否则你必须自己做一些类型推断来弄清楚它在做什么.所以在这种情况下,直接调用方法可能会更好BitSet.valueOf(long[]).
在性能方面 - 这并不总是最重要的 - 我认为直接方法调用可能比一系列map操作表现更好.通过额外的流操作传递值可能涉及两个方法调用,以及Lambda Metafactory调用额外lambda的开销.此外,直接方法调用可能更容易通过JIT和内联优化,而不是通过流传递值.但我还没有证实这一点.
| 归档时间: |
|
| 查看次数: |
1339 次 |
| 最近记录: |