在 java 中添加后缀 8 种方式
Add postfix in java 8 way
我需要一个函数,它 returns 一个包含 {XXX11, XXX12, XXX13, XXX14, XXX21, ... , XXX43, XXX44}
的集合,其中 XXX
是函数的整数参数。 Java8风格的优雅方式是什么?如果前缀是一位数字,我已经完成如下:
/**
* I need to get {<base>11, <base>12, ..., <base>44} but can't...
* @return {<base>1, <base>2, <base>3, <base>4}
*/
Set<Integer> addOnlyOnePrefix(int base){
return IntStream.range(1, 4).map(prefix -> base*10 + prefix)
.boxed().collect(Collectors.toSet());
}
最简单的方法可能是只生成 16 个值:
Set<Integer> addOnlyTwoPrefixes(int base) {
return IntStream.range(0, 16)
.map(prefix ->
base * 100 + // Leading digits
10 + 10 * (prefix / 4) + // Penultimate digit
1 + (prefix % 4)) // Last digit
.boxed()
.collect(Collectors.toSet());
}
10+ 和 1+ 是考虑到 prefix / 4
和 prefix % 4
在 0-3 范围内而不是 1-4 范围内。
你可以flatMap
.
先生成一个1..4
的IntStream
,然后乘以10。然后flatMap
另一个1..4
的IntStream
,得到11,12..21,22..
.
将 base
乘以 100
并将其添加到 IntStream
:
Set<Integer> addTwoPrefixes(final int base) {
final int prefix = base * 100;
return IntStream
.rangeClosed(1, 4).map(i -> i * 10)
.flatMap(i -> IntStream.rangeClosed(1, 4).map(j -> i + j))
.map(i -> base + i)
.boxed()
.collect(toCollection(LinkedHashSet::new));
}
注意,我已收集到 LinkedHashSet
以保持顺序。
您可以使用递归来编写一个添加 n 个前缀的方法:
static IntStream addNPrefixes(int base, int n) {
return n == 0 ? IntStream.of(base) : addNPrefixes(base, n - 1)
.flatMap(b -> IntStream.rangeClosed(1, 4).map(prefix -> b * 10 + prefix));
}
那么您想要的方法如下所示:
static Set<Integer> addTwoPrefixesThenCollectToSet(int base) {
return addNPrefixes(base, 2).boxed().collect(Collectors.toSet());
}
很容易更改第一种方法,以便您也可以传入前缀生成函数:
static IntStream addNPrefixes(int base, int n, Supplier<IntStream> prefixes) {
return n == 0 ? IntStream.of(base) : addNPrefixes(base, n - 1, prefixes)
.flatMap(b -> prefixes.get().map(prefix -> b * 10 + prefix));
}
我需要一个函数,它 returns 一个包含 {XXX11, XXX12, XXX13, XXX14, XXX21, ... , XXX43, XXX44}
的集合,其中 XXX
是函数的整数参数。 Java8风格的优雅方式是什么?如果前缀是一位数字,我已经完成如下:
/**
* I need to get {<base>11, <base>12, ..., <base>44} but can't...
* @return {<base>1, <base>2, <base>3, <base>4}
*/
Set<Integer> addOnlyOnePrefix(int base){
return IntStream.range(1, 4).map(prefix -> base*10 + prefix)
.boxed().collect(Collectors.toSet());
}
最简单的方法可能是只生成 16 个值:
Set<Integer> addOnlyTwoPrefixes(int base) {
return IntStream.range(0, 16)
.map(prefix ->
base * 100 + // Leading digits
10 + 10 * (prefix / 4) + // Penultimate digit
1 + (prefix % 4)) // Last digit
.boxed()
.collect(Collectors.toSet());
}
10+ 和 1+ 是考虑到 prefix / 4
和 prefix % 4
在 0-3 范围内而不是 1-4 范围内。
你可以flatMap
.
先生成一个1..4
的IntStream
,然后乘以10。然后flatMap
另一个1..4
的IntStream
,得到11,12..21,22..
.
将 base
乘以 100
并将其添加到 IntStream
:
Set<Integer> addTwoPrefixes(final int base) {
final int prefix = base * 100;
return IntStream
.rangeClosed(1, 4).map(i -> i * 10)
.flatMap(i -> IntStream.rangeClosed(1, 4).map(j -> i + j))
.map(i -> base + i)
.boxed()
.collect(toCollection(LinkedHashSet::new));
}
注意,我已收集到 LinkedHashSet
以保持顺序。
您可以使用递归来编写一个添加 n 个前缀的方法:
static IntStream addNPrefixes(int base, int n) {
return n == 0 ? IntStream.of(base) : addNPrefixes(base, n - 1)
.flatMap(b -> IntStream.rangeClosed(1, 4).map(prefix -> b * 10 + prefix));
}
那么您想要的方法如下所示:
static Set<Integer> addTwoPrefixesThenCollectToSet(int base) {
return addNPrefixes(base, 2).boxed().collect(Collectors.toSet());
}
很容易更改第一种方法,以便您也可以传入前缀生成函数:
static IntStream addNPrefixes(int base, int n, Supplier<IntStream> prefixes) {
return n == 0 ? IntStream.of(base) : addNPrefixes(base, n - 1, prefixes)
.flatMap(b -> prefixes.get().map(prefix -> b * 10 + prefix));
}