我想检查一下,LongStream
是否包含至少一次特定号码,但不完全包含此号码:
我的方法:
public static boolean containsNum(LongStream input, int n) {
return input.anyMatch(i -> i == n);
}
试验:
assertEquals(false, containsNum(LongStream.of(1, 2, 3), 19)); // ok
assertEquals(true, containsNum(LongStream.of(1, 2, 3, 19), 19)); //ok
assertEquals(true, containsNum(LongStream.of(1, 19, 19), 19)); //ok
assertEquals(false, containsNum(LongStream.of(1), 19)); //ok
assertEquals(false, containsNum(LongStream.of(19, 19), 19)); // FAIL
assertEquals(false, containsNum(LongStream.of(19), 19)); //FAIL
我知道anyMatch
无法解决我的问题,但我找到了最好的解决方案。我怎样才能通过所有测试?
答案 0 :(得分:10)
这听起来像是一个减少功能,正如安迪的回答所显示的那样,但是只要找到数字和不同的数字,这就会通过整个流而不是停止。
问题在于,流的那些...Match
方法一次只能查看一个元素,即您必须在某些外部状态变量中保存有关传递元素的知识。 wero和Roland在他们的答案中证明了这一点。
不依赖于外部状态而只检查所需数量的元素的一种可能性是:
boolean pass = longStream.map(l -> l == number ? 1 : 0)
.distinct()
.limit(2)
.count()
== 2;
答案 1 :(得分:2)
你可以减少流量,保留一对布尔值:
假设你有一些Pair
课;然后:
Stream<Pair> pairs =
input.map(i -> (i == n) ? Pair.of(true, false) : Pair.of(false, true));
然后,通过将两个元素组合在一起来减少这个流:
Pair reduces =
pairs.reduce(
Pair.of(false, false),
(a, b) -> Pair.of(a.first || b.first, a.second || b.second));
然后检查(并返回)两个元素都为真:
return reduced.first && reduced.second;
答案 2 :(得分:1)
的xD:
public static boolean containsNum(LongStream input, int n) {
LongSummaryStatistics summary = input.map(i -> i == n ? 1 : 0).summaryStatistics();
return summary.getMax() == 1 && summary.getMin() == 0;
}
说明:
summary.getMax() == 1
:至少找到一个n summary.getMin() == 0
:至少找到一个非n 答案 3 :(得分:0)
基于wero's回答:
public static boolean containsNum(LongStream input, int n) {
final AtomicBoolean different = new AtomicBoolean();
final AtomicBoolean equals = new AtomicBoolean();
return input.anyMatch(i -> {
different.compareAndSet(false, i != n);
equals.compareAndSet(false, i == n);
return different.get() && equals.get();
});
}
答案 4 :(得分:-2)
如果您看到n
和非n
:
public static boolean containsNum(LongStream input, int n) {
boolean[] seen = new boolean[2];
return input.anyMatch(i -> { seen[i==n ? 0 : 1] = true; return seen[0] && seen[1]; });
}