From b2eff6727a7b413f8a8a716d9aaa77535229631a Mon Sep 17 00:00:00 2001 From: haojin <2678432321@qq.com> Date: Sun, 18 Apr 2021 19:27:30 +0800 Subject: [PATCH 1/3] [#376] Implement shortcut for 0.0 and 1.0 percentile calculations, and add a new test --- .../src/main/java/org/jooq/lambda/Agg.java | 16 ++-- .../java/org/jooq/lambda/CollectorTests.java | 74 +++++++++++++++++++ 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/jOOL-java-8/src/main/java/org/jooq/lambda/Agg.java b/jOOL-java-8/src/main/java/org/jooq/lambda/Agg.java index ebd6e0e9..04f234ed 100644 --- a/jOOL-java-8/src/main/java/org/jooq/lambda/Agg.java +++ b/jOOL-java-8/src/main/java/org/jooq/lambda/Agg.java @@ -911,6 +911,17 @@ else if (l1[0] == null) if (percentile < 0.0 || percentile > 1.0) throw new IllegalArgumentException("Percentile must be between 0.0 and 1.0"); + if (percentile == 0.0) + // If percentile is 0, this is the same as taking the item with the minimum value. + return minBy(function, comparator); + else if (percentile == 1.0) + // If percentile is 1, this is the same as taking the item with the maximum value, + // If there are multiple maxima, take the last one. + return maxBy(function, (o1, o2) -> { + int compareResult = comparator.compare(o1, o2); + return compareResult == 0 ? -1 : compareResult; + }); + // At a later stage, we'll optimise this implementation in case that function is the identity function return Collector.of( () -> new ArrayList>(), @@ -929,11 +940,6 @@ else if (size == 1) l.sort(Comparator.comparing(t -> t.v2, comparator)); - if (percentile == 0.0) - return Optional.of(l.get(0).v1); - else if (percentile == 1.0) - return Optional.of(l.get(size - 1).v1); - // x.5 should be rounded down return Optional.of(l.get((int) -Math.round(-(size * percentile + 0.5)) - 1).v1); } diff --git a/jOOL-java-8/src/test/java/org/jooq/lambda/CollectorTests.java b/jOOL-java-8/src/test/java/org/jooq/lambda/CollectorTests.java index 815ec94e..d6952a6b 100644 --- a/jOOL-java-8/src/test/java/org/jooq/lambda/CollectorTests.java +++ b/jOOL-java-8/src/test/java/org/jooq/lambda/CollectorTests.java @@ -34,6 +34,7 @@ import static org.junit.Assert.assertEquals; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collector; import java.util.stream.Stream; @@ -308,6 +309,79 @@ public void testPercentileWithStringsAndFunction() { Utils.assertThrows(IllegalArgumentException.class, () -> Stream.of("a").collect(percentileBy(2, String::length))); } + @Test + public void testPercentileWithStringsAndFunctionWithDifferentValues() { + + // In the test testPercentileWithStringsAndFunction, the values (length) of the items are all the same, + // The function used in this test will take the first character of each string to be compared. + Function getFirstLetter = s -> s.length() == 0 ? 0 : s.charAt(0); + + // Min + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.0, getFirstLetter))); + + // 0.25 percentile + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.25, getFirstLetter))); + + // Median + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.5, getFirstLetter))); + + // 0.75 percentile + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("t"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.75, getFirstLetter))); + + // Max + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("t"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("u"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("v"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(1.0, getFirstLetter))); + } + @Test public void testRank() { From f3ec5e4aa182f6e6137abab0c5536d3f39f6a517 Mon Sep 17 00:00:00 2001 From: haojin <2678432321@qq.com> Date: Mon, 19 Apr 2021 01:42:37 +0800 Subject: [PATCH 2/3] [#376] Implement shortcut for 0.0 and 1.0 percentile calculations, and add a new test --- jOOL/src/main/java/org/jooq/lambda/Agg.java | 16 ++-- .../java/org/jooq/lambda/CollectorTests.java | 75 +++++++++++++++++++ 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/jOOL/src/main/java/org/jooq/lambda/Agg.java b/jOOL/src/main/java/org/jooq/lambda/Agg.java index ebd6e0e9..04f234ed 100644 --- a/jOOL/src/main/java/org/jooq/lambda/Agg.java +++ b/jOOL/src/main/java/org/jooq/lambda/Agg.java @@ -911,6 +911,17 @@ else if (l1[0] == null) if (percentile < 0.0 || percentile > 1.0) throw new IllegalArgumentException("Percentile must be between 0.0 and 1.0"); + if (percentile == 0.0) + // If percentile is 0, this is the same as taking the item with the minimum value. + return minBy(function, comparator); + else if (percentile == 1.0) + // If percentile is 1, this is the same as taking the item with the maximum value, + // If there are multiple maxima, take the last one. + return maxBy(function, (o1, o2) -> { + int compareResult = comparator.compare(o1, o2); + return compareResult == 0 ? -1 : compareResult; + }); + // At a later stage, we'll optimise this implementation in case that function is the identity function return Collector.of( () -> new ArrayList>(), @@ -929,11 +940,6 @@ else if (size == 1) l.sort(Comparator.comparing(t -> t.v2, comparator)); - if (percentile == 0.0) - return Optional.of(l.get(0).v1); - else if (percentile == 1.0) - return Optional.of(l.get(size - 1).v1); - // x.5 should be rounded down return Optional.of(l.get((int) -Math.round(-(size * percentile + 0.5)) - 1).v1); } diff --git a/jOOL/src/test/java/org/jooq/lambda/CollectorTests.java b/jOOL/src/test/java/org/jooq/lambda/CollectorTests.java index 815ec94e..af583061 100644 --- a/jOOL/src/test/java/org/jooq/lambda/CollectorTests.java +++ b/jOOL/src/test/java/org/jooq/lambda/CollectorTests.java @@ -34,6 +34,7 @@ import static org.junit.Assert.assertEquals; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collector; import java.util.stream.Stream; @@ -308,6 +309,80 @@ public void testPercentileWithStringsAndFunction() { Utils.assertThrows(IllegalArgumentException.class, () -> Stream.of("a").collect(percentileBy(2, String::length))); } + @Test + public void testPercentileWithStringsAndFunctionWithDifferentValues() { + + // In the test testPercentileWithStringsAndFunction, the values (length) of the items are all the same, + // The function used in this test will take the first character of each string to be compared. + + Function getFirstLetter = s -> s.length() == 0 ? 0 : s.charAt(0); + + // Min + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.0, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.0, getFirstLetter))); + + // 0.25 percentile + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.25, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.25, getFirstLetter))); + + // Median + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.5, getFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.5, getFirstLetter))); + + // 0.75 percentile + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.75, getFirstLetter))); + assertEquals(Optional.of("t"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.75, getFirstLetter))); + + // Max + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("t"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("u"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(1.0, getFirstLetter))); + assertEquals(Optional.of("v"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(1.0, getFirstLetter))); + } + @Test public void testRank() { From 012e5c84da13f598f58f8c4497692b548ae836a5 Mon Sep 17 00:00:00 2001 From: haojin <2678432321@qq.com> Date: Fri, 23 Apr 2021 16:35:53 +0800 Subject: [PATCH 3/3] Implement shortcut for 0.0 and 1.0 percentile calculations, and add two new tests --- .../src/main/java/org/jooq/lambda/Agg.java | 1 + .../java/org/jooq/lambda/CollectorTests.java | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/jOOL-java-8/src/main/java/org/jooq/lambda/Agg.java b/jOOL-java-8/src/main/java/org/jooq/lambda/Agg.java index 04f234ed..2a06246f 100644 --- a/jOOL-java-8/src/main/java/org/jooq/lambda/Agg.java +++ b/jOOL-java-8/src/main/java/org/jooq/lambda/Agg.java @@ -911,6 +911,7 @@ else if (l1[0] == null) if (percentile < 0.0 || percentile > 1.0) throw new IllegalArgumentException("Percentile must be between 0.0 and 1.0"); + // CS304 Issue link: https://github.com/jOOQ/jOOL/issues/376 if (percentile == 0.0) // If percentile is 0, this is the same as taking the item with the minimum value. return minBy(function, comparator); diff --git a/jOOL-java-8/src/test/java/org/jooq/lambda/CollectorTests.java b/jOOL-java-8/src/test/java/org/jooq/lambda/CollectorTests.java index d6952a6b..854b4a74 100644 --- a/jOOL-java-8/src/test/java/org/jooq/lambda/CollectorTests.java +++ b/jOOL-java-8/src/test/java/org/jooq/lambda/CollectorTests.java @@ -312,6 +312,7 @@ public void testPercentileWithStringsAndFunction() { @Test public void testPercentileWithStringsAndFunctionWithDifferentValues() { + // CS304 (manually written) Issue link: https://github.com/jOOQ/jOOL/issues/376 // In the test testPercentileWithStringsAndFunction, the values (length) of the items are all the same, // The function used in this test will take the first character of each string to be compared. Function getFirstLetter = s -> s.length() == 0 ? 0 : s.charAt(0); @@ -382,6 +383,79 @@ public void testPercentileWithStringsAndFunctionWithDifferentValues() { assertEquals(Optional.of("v"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(1.0, getFirstLetter))); } + @Test + public void testPercentileWithStringsAndFunctionWithDifferentValues2() { + + // CS304 (manually written) Issue link: https://github.com/jOOQ/jOOL/issues/376 + // The function used in this test will take the minus value of the first character of each string to be compared. + Function getMinusValueOfFirstLetter = s -> s.length() == 0 ? 0 : (int) -s.charAt(0); + + // Min + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("t"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("u"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("v"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.0, getMinusValueOfFirstLetter))); + + // 0.25 + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("i"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("j"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("t"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.25, getMinusValueOfFirstLetter))); + + // 0.5 + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("d"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.5, getMinusValueOfFirstLetter))); + + // 0.75 + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("b"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("c"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(0.75, getMinusValueOfFirstLetter))); + + // Max + assertEquals(Optional.of("a"), Stream.of("a").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + assertEquals(Optional.of("a"), Stream.of("a", "b", "c", "d", "j", "i", "c", "c", "t", "u", "v").collect(percentileBy(1.0, getMinusValueOfFirstLetter))); + } + @Test public void testRank() {