jOOQ / jOOL

jOOλ - The Missing Parts in Java 8 jOOλ improves the JDK libraries in areas where the Expert Group's focus was elsewhere. It adds tuple support, function support, and a lot of additional functionality around sequential Streams. The JDK 8's main efforts (default methods, lambdas, and the Stream API) were focused around maintaining backwards compatibility and implementing a functional API for parallelism.
http://www.jooq.org/products
Apache License 2.0
2.09k stars 168 forks source link

limitWhile (and other limit* methods) problem #318

Closed cigaly closed 7 years ago

cigaly commented 7 years ago

This test will generate ArrayIndexOftOfBoundsException:

@Test
public void limitWhite() {
    Integer array[] = { 1, 2, -1 };
    UnaryOperator<Integer> iterate = x -> array[x];
    Predicate<Integer> filter = x -> x >= 0;

    Seq<Integer> seq1 = Seq.iterate(0, iterate);
    Seq<Integer> seq2 = seq1.limitWhile(filter);
    // After limitWhile seq2 should be { 0, 1, 2 }
    Seq<Integer> seq3 = seq2.map(x -> x + 1);
    // After map seq3 should be { 1, 2, 3 }
    int seq4 = seq3.foldLeft(1, (x, y) -> x * y);
    // Rezult should be 6
    Assert.assertEquals(6, seq4);
}

After filter predicate.test(-1) returns false, iterate.apply(-1) should newer be called.

Here is equivalent code in scala that is working as expected:

val array = Array(1, 2, -1)
def str(x: Int): Stream[Int] = x #:: str(array(x))
val seq1 = str(0)
val seq2 = seq1.takeWhile(x => x >= 0)
val seq3 = seq2.map(x => x + 1)
val seq4 = seq3.foldLeft(1)((x, y) => x * y)
lukaseder commented 7 years ago

Thank you very much for reporting. Will look into this immediately.

lukaseder commented 7 years ago

It might well be that jOOλ could optimise the lazy evaluation of the Seq.iterate() calls (currently passing this through to Stream) to avoid the application of the call array[-1], but in any case, defensive programming would probably suggest this implementation, instead:

UnaryOperator<Integer> iterate = x -> x >= 0 ? array[x] : x;
cigaly commented 7 years ago

You are right, it could be coded that way, still, I would not call that a feature.

lukaseder commented 7 years ago

still, I would not call that a feature.

Well, I didn't, did I? :)

image

cigaly commented 7 years ago

No, that's true :-)

tlinkowski commented 7 years ago

This issue is a duplicate of #309 :) Fortunately, it's trivial to fix - see https://github.com/jOOQ/jOOL/issues/309#issuecomment-298250192.

cigaly commented 7 years ago

That's correct. With your proposed change thsi is working properly.