From 09bd0580c6691fe903b549739552cba40dc71428 Mon Sep 17 00:00:00 2001 From: lukaseder Date: Sun, 13 Mar 2016 18:05:53 +0100 Subject: [PATCH] [#212] Add Collectable.bitAnd(), bitOr() including mapping overloads --- src/main/java/org/jooq/lambda/Agg.java | 132 +++++++++++++++++- .../java/org/jooq/lambda/Collectable.java | 46 +++++- src/main/java/org/jooq/lambda/SeqImpl.java | 43 ++++++ src/main/java/org/jooq/lambda/Sum.java | 128 +++++++++++++++-- src/main/java/org/jooq/lambda/WindowImpl.java | 43 ++++++ src/test/java/org/jooq/lambda/SeqTest.java | 20 +++ 6 files changed, 393 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/jooq/lambda/Agg.java b/src/main/java/org/jooq/lambda/Agg.java index 33f42e80..7d4a8c29 100644 --- a/src/main/java/org/jooq/lambda/Agg.java +++ b/src/main/java/org/jooq/lambda/Agg.java @@ -24,8 +24,11 @@ import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.function.Predicate; +import java.util.function.ToIntFunction; +import java.util.function.ToLongFunction; import org.jooq.lambda.tuple.Tuple2; +import static org.jooq.lambda.tuple.Tuple.tuple; /** * A set of additional {@link Collector} implementations. @@ -81,8 +84,7 @@ public class Agg { * type of {@link Number}. */ public static Collector> sum(Function function) { - return Collector.of( - () -> (Sum[]) new Sum[1], + return Collector.of(() -> (Sum[]) new Sum[1], (s, v) -> { if (s[0] == null) s[0] = Sum.create(function.apply(v)); @@ -93,7 +95,7 @@ public class Agg { s1[0].add(s2[0]); return s1; }, - s -> s[0] == null ? Optional.empty() : Optional.of(s[0].sum()) + s -> s[0] == null ? Optional.empty() : Optional.of(s[0].result()) ); } @@ -274,6 +276,130 @@ public class Agg { return allMatch(predicate.negate()); } + /** + * Get a {@link Collector} that calculates BIT_AND() for any + * type of {@link Number}. + */ + public static Collector> bitAnd() { + return bitAnd(t -> t); + } + + /** + * Get a {@link Collector} that calculates the BIT_AND() for any + * type of {@link Number}. + */ + public static Collector> bitAnd(Function function) { + return Collector.of(() -> (Sum[]) new Sum[1], + (s, v) -> { + if (s[0] == null) + s[0] = Sum.create(function.apply(v)); + else + s[0].and(function.apply(v)); + }, + (s1, s2) -> { + s1[0].and(s2[0]); + return s1; + }, + s -> s[0] == null ? Optional.empty() : Optional.of(s[0].result()) + ); + } + + /** + * Get a {@link Collector} that calculates the BIT_AND() for any + * type of {@link Number}. + */ + public static Collector bitAndInt(ToIntFunction function) { + return Collector.of(() -> new int[] { Integer.MAX_VALUE }, + (s, v) -> { + s[0] = s[0] & function.applyAsInt(v); + }, + (s1, s2) -> { + s1[0] = s1[0] & s2[0]; + return s1; + }, + s -> s[0] + ); + } + + /** + * Get a {@link Collector} that calculates the BIT_AND() for any + * type of {@link Number}. + */ + public static Collector bitAndLong(ToLongFunction function) { + return Collector.of(() -> new long[] { Long.MAX_VALUE }, + (s, v) -> { + s[0] = s[0] & function.applyAsLong(v); + }, + (s1, s2) -> { + s1[0] = s1[0] & s2[0]; + return s1; + }, + s -> s[0] + ); + } + + /** + * Get a {@link Collector} that calculates BIT_OR() for any + * type of {@link Number}. + */ + public static Collector> bitOr() { + return bitOr(t -> t); + } + + /** + * Get a {@link Collector} that calculates the BIT_OR() for any + * type of {@link Number}. + */ + public static Collector> bitOr(Function function) { + return Collector.of(() -> (Sum[]) new Sum[1], + (s, v) -> { + if (s[0] == null) + s[0] = Sum.create(function.apply(v)); + else + s[0].or(function.apply(v)); + }, + (s1, s2) -> { + s1[0].or(s2[0]); + return s1; + }, + s -> s[0] == null ? Optional.empty() : Optional.of(s[0].result()) + ); + } + + /** + * Get a {@link Collector} that calculates the BIT_OR() for any + * type of {@link Number}. + */ + public static Collector bitOrInt(ToIntFunction function) { + return Collector.of(() -> new int[1], + (s, v) -> { + s[0] = s[0] | function.applyAsInt(v); + }, + (s1, s2) -> { + s1[0] = s1[0] | s2[0]; + return s1; + }, + s -> s[0] + ); + } + + /** + * Get a {@link Collector} that calculates the BIT_OR() for any + * type of {@link Number}. + */ + public static Collector bitOrLong(ToLongFunction function) { + return Collector.of(() -> new long[1], + (s, v) -> { + s[0] = s[0] | function.applyAsLong(v); + }, + (s1, s2) -> { + s1[0] = s1[0] | s2[0]; + return s1; + }, + s -> s[0] + ); + } + /** * Get a {@link Collector} that calculates the MODE() function. */ diff --git a/src/main/java/org/jooq/lambda/Collectable.java b/src/main/java/org/jooq/lambda/Collectable.java index 662688ff..f9e154b3 100644 --- a/src/main/java/org/jooq/lambda/Collectable.java +++ b/src/main/java/org/jooq/lambda/Collectable.java @@ -15,13 +15,16 @@ */ package org.jooq.lambda; +import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; +import java.util.OptionalLong; import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; @@ -31,6 +34,7 @@ import java.util.function.ToLongFunction; import java.util.stream.Collector; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Generated; import org.jooq.lambda.tuple.Tuple; import org.jooq.lambda.tuple.Tuple10; @@ -554,6 +558,46 @@ default predicate); + /** + * Collect all bits in this stream into a single value by applying bitwise and. + */ + Optional bitAnd(); + + /** + * Collect all bits in this stream into a single value by applying bitwise and. + */ + Optional bitAnd(Function function); + + /** + * Collect all bits in this stream into a single value by applying bitwise and. + */ + int bitAndInt(ToIntFunction function); + + /** + * Collect all bits in this stream into a single value by applying bitwise and. + */ + long bitAndLong(ToLongFunction function); + + /** + * Collect all bits in this stream into a single value by applying bitwise or. + */ + Optional bitOr(); + + /** + * Collect all bits in this stream into a single value by applying bitwise or. + */ + Optional bitOr(Function function); + + /** + * Collect all bits in this stream into a single value by applying bitwise or. + */ + int bitOrInt(ToIntFunction function); + + /** + * Collect all bits in this stream into a single value by applying bitwise or. + */ + long bitOrLong(ToLongFunction function); + /** * Collect the collectable into an {@link ArrayList}. */ diff --git a/src/main/java/org/jooq/lambda/SeqImpl.java b/src/main/java/org/jooq/lambda/SeqImpl.java index 0f7350d6..812b6d79 100644 --- a/src/main/java/org/jooq/lambda/SeqImpl.java +++ b/src/main/java/org/jooq/lambda/SeqImpl.java @@ -26,6 +26,9 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; +import java.util.OptionalLong; import java.util.Set; import java.util.Spliterator; import java.util.function.BiConsumer; @@ -393,6 +396,46 @@ public boolean noneMatch(Predicate predicate) { return stream().noneMatch(predicate); } + @Override + public Optional bitAnd() { + return collect(Agg.bitAnd()); + } + + @Override + public Optional bitAnd(Function function) { + return collect(Agg.bitAnd(function)); + } + + @Override + public int bitAndInt(ToIntFunction function) { + return collect(Agg.bitAndInt(function)); + } + + @Override + public long bitAndLong(ToLongFunction function) { + return collect(Agg.bitAndLong(function)); + } + + @Override + public Optional bitOr() { + return collect(Agg.bitOr()); + } + + @Override + public Optional bitOr(Function function) { + return collect(Agg.bitOr(function)); + } + + @Override + public int bitOrInt(ToIntFunction function) { + return collect(Agg.bitOrInt(function)); + } + + @Override + public long bitOrLong(ToLongFunction function) { + return collect(Agg.bitOrLong(function)); + } + @Override public Optional findFirst() { return stream().findFirst(); diff --git a/src/main/java/org/jooq/lambda/Sum.java b/src/main/java/org/jooq/lambda/Sum.java index 8bb01f4f..23f1df81 100644 --- a/src/main/java/org/jooq/lambda/Sum.java +++ b/src/main/java/org/jooq/lambda/Sum.java @@ -26,7 +26,7 @@ abstract class Sum { long count; void add(Sum sum) { - add0(sum.sum()); + add0(sum.result()); count += sum.count; } @@ -34,9 +34,27 @@ void add(N value) { add0(value); count += 1; } + + void and(Sum sum) { + and0(sum.result()); + } + + void and(N value) { + and0(value); + } + + void or(Sum sum) { + or0(sum.result()); + } + + void or(N value) { + or0(value); + } abstract void add0(N value); - abstract N sum(); + abstract void and0(N value); + abstract void or0(N value); + abstract N result(); abstract N avg(); @SuppressWarnings({ "unchecked", "rawtypes" }) @@ -67,21 +85,31 @@ else if (value instanceof BigDecimal) } static class OfByte extends Sum { - byte sum; + byte result; @Override void add0(Byte value) { - sum += value; + result += value; } @Override - Byte sum() { - return sum; + Byte result() { + return result; + } + + @Override + void and0(Byte value) { + result &= value; + } + + @Override + void or0(Byte value) { + result |= value; } @Override Byte avg() { - return (byte) (sum / count); + return (byte) (result / count); } } static class OfShort extends Sum { @@ -93,7 +121,17 @@ void add0(Short value) { } @Override - Short sum() { + void and0(Short value) { + sum &= value; + } + + @Override + void or0(Short value) { + sum |= value; + } + + @Override + Short result() { return sum; } @@ -111,10 +149,20 @@ void add0(Integer value) { } @Override - Integer sum() { - return sum; + void and0(Integer value) { + sum &= value; } + @Override + void or0(Integer value) { + sum |= value; + } + + @Override + Integer result() { + return sum; + } + @Override Integer avg() { return (int) (sum / count); @@ -129,7 +177,17 @@ void add0(Long value) { } @Override - Long sum() { + void and0(Long value) { + sum &= value; + } + + @Override + void or0(Long value) { + sum |= value; + } + + @Override + Long result() { return sum; } @@ -147,7 +205,17 @@ void add0(Float value) { } @Override - Float sum() { + void and0(Float value) { + throw new UnsupportedOperationException(); + } + + @Override + void or0(Float value) { + throw new UnsupportedOperationException(); + } + + @Override + Float result() { return sum; } @@ -165,7 +233,17 @@ void add0(Double value) { } @Override - Double sum() { + void and0(Double value) { + throw new UnsupportedOperationException(); + } + + @Override + void or0(Double value) { + throw new UnsupportedOperationException(); + } + + @Override + Double result() { return sum; } @@ -183,7 +261,17 @@ void add0(BigInteger value) { } @Override - BigInteger sum() { + void and0(BigInteger value) { + throw new UnsupportedOperationException(); + } + + @Override + void or0(BigInteger value) { + throw new UnsupportedOperationException(); + } + + @Override + BigInteger result() { return sum; } @@ -201,7 +289,17 @@ void add0(BigDecimal value) { } @Override - BigDecimal sum() { + void and0(BigDecimal value) { + throw new UnsupportedOperationException(); + } + + @Override + void or0(BigDecimal value) { + throw new UnsupportedOperationException(); + } + + @Override + BigDecimal result() { return sum; } diff --git a/src/main/java/org/jooq/lambda/WindowImpl.java b/src/main/java/org/jooq/lambda/WindowImpl.java index d59a2bc5..1d18822a 100644 --- a/src/main/java/org/jooq/lambda/WindowImpl.java +++ b/src/main/java/org/jooq/lambda/WindowImpl.java @@ -28,6 +28,9 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; +import java.util.OptionalLong; import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; @@ -413,6 +416,46 @@ public boolean noneMatch(Predicate predicate) { return partition.cacheIf(completePartition(), () -> tuple("noneMatch", predicate), () -> window().noneMatch(predicate)); } + @Override + public Optional bitAnd() { + return partition.cacheIf(completePartition(), () -> tuple("bitAnd"), () -> window().bitAnd()); + } + + @Override + public Optional bitAnd(Function function) { + return partition.cacheIf(completePartition(), () -> tuple("bitAnd", function), () -> window().bitAnd(function)); + } + + @Override + public int bitAndInt(ToIntFunction function) { + return partition.cacheIf(completePartition(), () -> tuple("bitAndInt", function), () -> window().bitAndInt(function)); + } + + @Override + public long bitAndLong(ToLongFunction function) { + return partition.cacheIf(completePartition(), () -> tuple("bitAndLong", function), () -> window().bitAndLong(function)); + } + + @Override + public Optional bitOr() { + return partition.cacheIf(completePartition(), () -> tuple("bitOr"), () -> window().bitOr()); + } + + @Override + public Optional bitOr(Function function) { + return partition.cacheIf(completePartition(), () -> tuple("bitOr", function), () -> window().bitOr(function)); + } + + @Override + public int bitOrInt(ToIntFunction function) { + return partition.cacheIf(completePartition(), () -> tuple("bitOrInt", function), () -> window().bitOrInt(function)); + } + + @Override + public long bitOrLong(ToLongFunction function) { + return partition.cacheIf(completePartition(), () -> tuple("bitOrLong", function), () -> window().bitOrLong(function)); + } + @Override public R collect(Collector collector) { return partition.cacheIf(completePartition(), () -> tuple("collect", collector), () -> window().collect(collector)); diff --git a/src/test/java/org/jooq/lambda/SeqTest.java b/src/test/java/org/jooq/lambda/SeqTest.java index e7e3d266..11e624af 100644 --- a/src/test/java/org/jooq/lambda/SeqTest.java +++ b/src/test/java/org/jooq/lambda/SeqTest.java @@ -1677,6 +1677,26 @@ public void testAvg() { assertEquals(Optional.of(1.5), Seq.of(1.0, 2.0).avg()); assertEquals(Optional.of(2.0), Seq.of(1.0, 2.0, 3.0).avg()); } + + @Test + public void testBitAnd() { + int value = 31 & 15 & 7 & 3; + + assertEquals(Optional.of(value), Seq.of(31, 15, 7, 3).bitAnd()); + assertEquals(Optional.of((long) value), Seq.of(31, 15, 7, 3).bitAnd(t -> (long) t)); + assertEquals(value, Seq.of(31, 15, 7, 3).bitAndInt(t -> t)); + assertEquals((long) value, Seq.of(31, 15, 7, 3).bitAndLong(t -> t)); + } + + @Test + public void testBitOr() { + int value = 1 | 2 | 4 | 8; + + assertEquals(Optional.of(value), Seq.of(1, 2, 4, 8).bitOr()); + assertEquals(Optional.of((long) value), Seq.of(1, 2, 4, 8).bitOr(t -> (long) t)); + assertEquals(value, Seq.of(1, 2, 4, 8).bitOrInt(t -> t)); + assertEquals((long) value, Seq.of(1, 2, 4, 8).bitOrLong(t -> t)); + } @Test public void testCollect() {