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 8c0a5e23..a13b87cb 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 @@ -906,49 +906,37 @@ else if (l1[0] == null) /** * Get a {@link Collector} that calculates the derived PERCENTILE_DISC(percentile) function given a specific ordering. - * - * @param function map the items in the streams into values - * @param comparator comparator used for sorting the items - * @return a collector that calculates the derived PERCENTILE_DISC(percentile) function */ public static Collector> percentileBy(double percentile, Function function, Comparator comparator) { 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); 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>(), - (l, v) -> l.add(tuple(v, function.apply(v))), - (l1, l2) -> { - l1.addAll(l2); - return l1; - }, - l -> { - int size = l.size(); + return collectingAndThen(maxAllBy(function, comparator), s -> s.findLast()); + else + return Collector.of( + () -> new ArrayList>(), + (l, v) -> l.add(tuple(v, function.apply(v))), + (l1, l2) -> { + l1.addAll(l2); + return l1; + }, + l -> { + int size = l.size(); - if (size == 0) - return Optional.empty(); - else if (size == 1) - return Optional.of(l.get(0).v1); + if (size == 0) + return Optional.empty(); + else if (size == 1) + return Optional.of(l.get(0).v1); - l.sort(Comparator.comparing(t -> t.v2, comparator)); + l.sort(Comparator.comparing(t -> t.v2, comparator)); - // x.5 should be rounded down - return Optional.of(l.get((int) -Math.round(-(size * percentile + 0.5)) - 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/main/java/org/jooq/lambda/Agg.java b/jOOL/src/main/java/org/jooq/lambda/Agg.java index 8c0a5e23..a13b87cb 100644 --- a/jOOL/src/main/java/org/jooq/lambda/Agg.java +++ b/jOOL/src/main/java/org/jooq/lambda/Agg.java @@ -906,49 +906,37 @@ else if (l1[0] == null) /** * Get a {@link Collector} that calculates the derived PERCENTILE_DISC(percentile) function given a specific ordering. - * - * @param function map the items in the streams into values - * @param comparator comparator used for sorting the items - * @return a collector that calculates the derived PERCENTILE_DISC(percentile) function */ public static Collector> percentileBy(double percentile, Function function, Comparator comparator) { 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); 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>(), - (l, v) -> l.add(tuple(v, function.apply(v))), - (l1, l2) -> { - l1.addAll(l2); - return l1; - }, - l -> { - int size = l.size(); + return collectingAndThen(maxAllBy(function, comparator), s -> s.findLast()); + else + return Collector.of( + () -> new ArrayList>(), + (l, v) -> l.add(tuple(v, function.apply(v))), + (l1, l2) -> { + l1.addAll(l2); + return l1; + }, + l -> { + int size = l.size(); - if (size == 0) - return Optional.empty(); - else if (size == 1) - return Optional.of(l.get(0).v1); + if (size == 0) + return Optional.empty(); + else if (size == 1) + return Optional.of(l.get(0).v1); - l.sort(Comparator.comparing(t -> t.v2, comparator)); + l.sort(Comparator.comparing(t -> t.v2, comparator)); - // x.5 should be rounded down - return Optional.of(l.get((int) -Math.round(-(size * percentile + 0.5)) - 1).v1); - } - ); + // x.5 should be rounded down + return Optional.of(l.get((int) -Math.round(-(size * percentile + 0.5)) - 1).v1); + } + ); } /**