Java Long Stream contains a specific number

I want to check if a LongStream contains a certain number at least once, but does not completely consist of this number:

My approach:

 public static boolean containsNum(LongStream input, int n) { return input.anyMatch(i -> i == n); } 

Tests:

 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 

I know that anyMatch may not work in my problem, but the best solution I found. How can I go through all the tests?

+5
source share
5 answers

Sounds like a decrease function, as Andy's answer shows, but it will go through the whole stream, and not stop as soon as you find the number and another number.

The problem is that those methods ...Match threads only look at one element at a time, i.e. you will need to keep knowledge of the elements passed in some external state variable. and Roland demonstrates this in his answers.

One possibility, not relying on the external state, when checking the total number of elements as necessary:

 boolean pass = longStream.map(l -> l == number ? 1 : 0) .distinct() .limit(2) .count() == 2; 
+10
source

You can reduce the flow by storing a couple of gates:

  • The first, indicating whether at least one occurrence of n was detected;
  • The second indication is whether at least one occurrence of something other than n was detected.

Say you have a Pair class; then:

 Stream<Pair> pairs = input.map(i -> (i == n) ? Pair.of(true, false) : Pair.of(false, true)); 

Then reduce this stream by combining two elements:

 Pair reduces = pairs.reduce( Pair.of(false, false), (a, b) -> Pair.of(a.first || b.first, a.second || b.second)); 

Then check (and return) that both elements are correct:

 return reduced.first && reduced.second; 
+2
source

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; } 

Explanation:

  • summary.getMax() == 1 : at least one n was found
  • summary.getMin() == 0 : found at least one non-n
+1
source

Based on wero's answer:

  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(); }); } 
0
source

Watch if you saw n and not 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]; }); } 
-2
source

Source: https://habr.com/ru/post/1268346/


All Articles