如何使用 Java 8/lambda 执行嵌套的 'if' 语句?
How to perform nested 'if' statements using Java 8/lambda?
我有以下代码,想用 lambda 函数来实现它只是为了好玩。可以使用基本的聚合操作来完成吗?
List<Integer> result = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
if (10 % i == 0) {
result.add(i);
if (i != 5) {
result.add(10 / i);
}
}
}
使用 lambda:
List<Integer> result = IntStream.rangeClosed(1, 10)
.boxed()
.filter(i -> 10 % i == 0)
// a map or forEach function here?
// .map(return 10 / i -> if i != 5)
.collect(Collectors.toList());
您可以为 lambda 声明一个主体。例如:
Runnable run = () -> System.out.println("Hey");
可能是
Runnable run = () -> {
System.out.println("Hey");
};
在该正文中,您可以创建嵌套语句:
Runnable run = () -> {
int num = 5;
if(num == 5) {
System.out.println("Hey");
}
};
尝试使用 flatMap
:
List<Integer> result = IntStream.rangeClosed(1, 10)
.boxed()
.flatMap((i) -> {
List<Integer> results = new ArrayList<>();
if (10 % i == 0) {
results.add(i);
if (i != 5) {
results.add(10 / i);
}
}
return results.stream();
})
.collect(Collectors.toList());
你可以这样做:
List<Integer> result1 = IntStream
.rangeClosed(1, 10)
.boxed()
.filter(i -> 10 % i == 0)
.map(i -> (i != 5 ? Stream.of(i, 10 / i) : Stream.of(i)))
.flatMap(Function.identity())
.collect(Collectors.toList());
这里的基本观察是您的问题涉及 非同构 转换:单个输入元素可能映射到零个、一个或两个输出元素。每当您注意到这一点时,您应该立即开始寻找涉及 flatMap
而不是 map
的解决方案,因为这是实现这种通用转换的唯一方法。在您的特定情况下,您可以首先应用 filter
进行一对零元素映射,然后 flatMap
进行一对二映射:
List<Integer> result =
IntStream.rangeClosed(1, 10)
.filter(i -> 10 % i == 0)
.flatMap(i -> i == 5 ? IntStream.of(i) : IntStream.of(i, 10 / i))
.boxed()
.collect(toList());
(假设import static java.util.stream.Collectors.toList
)
在尝试将元素添加到管道或一对多映射时使用 flatMap
。 Map是一对一的映射。
ArrayList<Integer> result = (ArrayList<Integer>) IntStream.rangeClosed(1, 10)
.boxed()
.filter(i -> 10 % i == 0)
.flatMap((Integer i) -> {return i!=5 ? Stream.of(i, (10/i)):Stream.of(i);})
.collect(Collectors.toList());
这会产生与
相同的列表
ArrayList<Integer> result2 = new ArrayList<Integer>();
for (int i = 1; i <= 10; i++) {
if (10 % i == 0) {
result2.add(i);
if (i != 5) {
result2.add(10 / i);
}
}
}
如果您想知道哪种方法更快,循环方法比使用流快约 3 倍。
Benchmark Mode Cnt Score Error Units
testStreams.Bench.loops avgt 5 75.221 ± 0.576 ns/op
testStreams.Bench.streams avgt 5 257.713 ± 13.125 ns/op
我有以下代码,想用 lambda 函数来实现它只是为了好玩。可以使用基本的聚合操作来完成吗?
List<Integer> result = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
if (10 % i == 0) {
result.add(i);
if (i != 5) {
result.add(10 / i);
}
}
}
使用 lambda:
List<Integer> result = IntStream.rangeClosed(1, 10)
.boxed()
.filter(i -> 10 % i == 0)
// a map or forEach function here?
// .map(return 10 / i -> if i != 5)
.collect(Collectors.toList());
您可以为 lambda 声明一个主体。例如:
Runnable run = () -> System.out.println("Hey");
可能是
Runnable run = () -> {
System.out.println("Hey");
};
在该正文中,您可以创建嵌套语句:
Runnable run = () -> {
int num = 5;
if(num == 5) {
System.out.println("Hey");
}
};
尝试使用 flatMap
:
List<Integer> result = IntStream.rangeClosed(1, 10)
.boxed()
.flatMap((i) -> {
List<Integer> results = new ArrayList<>();
if (10 % i == 0) {
results.add(i);
if (i != 5) {
results.add(10 / i);
}
}
return results.stream();
})
.collect(Collectors.toList());
你可以这样做:
List<Integer> result1 = IntStream
.rangeClosed(1, 10)
.boxed()
.filter(i -> 10 % i == 0)
.map(i -> (i != 5 ? Stream.of(i, 10 / i) : Stream.of(i)))
.flatMap(Function.identity())
.collect(Collectors.toList());
这里的基本观察是您的问题涉及 非同构 转换:单个输入元素可能映射到零个、一个或两个输出元素。每当您注意到这一点时,您应该立即开始寻找涉及 flatMap
而不是 map
的解决方案,因为这是实现这种通用转换的唯一方法。在您的特定情况下,您可以首先应用 filter
进行一对零元素映射,然后 flatMap
进行一对二映射:
List<Integer> result =
IntStream.rangeClosed(1, 10)
.filter(i -> 10 % i == 0)
.flatMap(i -> i == 5 ? IntStream.of(i) : IntStream.of(i, 10 / i))
.boxed()
.collect(toList());
(假设import static java.util.stream.Collectors.toList
)
在尝试将元素添加到管道或一对多映射时使用 flatMap
。 Map是一对一的映射。
ArrayList<Integer> result = (ArrayList<Integer>) IntStream.rangeClosed(1, 10)
.boxed()
.filter(i -> 10 % i == 0)
.flatMap((Integer i) -> {return i!=5 ? Stream.of(i, (10/i)):Stream.of(i);})
.collect(Collectors.toList());
这会产生与
相同的列表ArrayList<Integer> result2 = new ArrayList<Integer>();
for (int i = 1; i <= 10; i++) {
if (10 % i == 0) {
result2.add(i);
if (i != 5) {
result2.add(10 / i);
}
}
}
如果您想知道哪种方法更快,循环方法比使用流快约 3 倍。
Benchmark Mode Cnt Score Error Units
testStreams.Bench.loops avgt 5 75.221 ± 0.576 ns/op
testStreams.Bench.streams avgt 5 257.713 ± 13.125 ns/op