This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git


The following commit(s) were added to refs/heads/master by this push:
     new 7045693  NUMBERS-135: Implementation details removed from public API.
7045693 is described below

commit 7045693efc63d9df82461bcb3e1adde2f043b0c1
Author: Gilles Sadowski <[email protected]>
AuthorDate: Sun Sep 29 02:21:38 2019 +0200

    NUMBERS-135: Implementation details removed from public API.
    
    "Comparator" implementation made "private".
    Factory method ("of").
---
 .../numbers/combinatorics/Combinations.java        | 136 +++++++--------------
 .../numbers/combinatorics/CombinationsTest.java    | 105 +++++++---------
 2 files changed, 92 insertions(+), 149 deletions(-)

diff --git 
a/commons-numbers-combinatorics/src/main/java/org/apache/commons/numbers/combinatorics/Combinations.java
 
b/commons-numbers-combinatorics/src/main/java/org/apache/commons/numbers/combinatorics/Combinations.java
index 691b2c1..c72711a 100644
--- 
a/commons-numbers-combinatorics/src/main/java/org/apache/commons/numbers/combinatorics/Combinations.java
+++ 
b/commons-numbers-combinatorics/src/main/java/org/apache/commons/numbers/combinatorics/Combinations.java
@@ -35,76 +35,30 @@ public class Combinations implements Iterable<int[]> {
     private final int n;
     /** Number of elements in each combination. */
     private final int k;
-    /** Iteration order. */
-    private final IterationOrder iterationOrder;
 
     /**
-     * Describes the type of iteration performed by the
-     * {@link #iterator() iterator}.
-     */
-    private enum IterationOrder {
-        /** Lexicographic order. */
-        LEXICOGRAPHIC
-    }
-
-   /**
-     * Creates an instance whose range is the k-element subsets of
-     * {0, ..., n - 1} represented as {@code int[]} arrays.
-     * <p>
-     * The iteration order is lexicographic: the arrays returned by the
-     * {@link #iterator() iterator} are sorted in descending order and
-     * they are visited in lexicographic order with significance from
-     * right to left.
-     * For example, {@code new Combinations(4, 2).iterator()} returns
-     * an iterator that will generate the following sequence of arrays
-     * on successive calls to
-     * {@code next()}:<br>
-     * {@code [0, 1], [0, 2], [1, 2], [0, 3], [1, 3], [2, 3]}
-     * </p>
-     * If {@code k == 0} an iterator containing an empty array is returned;
-     * if {@code k == n} an iterator containing [0, ..., n - 1] is returned.
-     *
      * @param n Size of the set from which subsets are selected.
      * @param k Size of the subsets to be enumerated.
      * @throws IllegalArgumentException if {@code n < 0}.
      * @throws IllegalArgumentException if {@code k > n} or {@code k < 0}.
      */
-    public Combinations(int n,
-                        int k) {
-        this(n, k, IterationOrder.LEXICOGRAPHIC);
+    private Combinations(int n,
+                         int k) {
+        BinomialCoefficient.checkBinomial(n, k);
+        this.n = n;
+        this.k = k;
     }
 
     /**
-     * Creates an instance whose range is the k-element subsets of
-     * {0, ..., n - 1} represented as {@code int[]} arrays.
-     * <p>
-     * If the {@code iterationOrder} argument is set to
-     * {@link IterationOrder#LEXICOGRAPHIC}, the arrays returned by the
-     * {@link #iterator() iterator} are sorted in descending order and
-     * they are visited in lexicographic order with significance from
-     * right to left.
-     * For example, {@code new Combinations(4, 2).iterator()} returns
-     * an iterator that will generate the following sequence of arrays
-     * on successive calls to
-     * {@code next()}:<br>
-     * {@code [0, 1], [0, 2], [1, 2], [0, 3], [1, 3], [2, 3]}
-     * </p>
-     * If {@code k == 0} an iterator containing an empty array is returned;
-     * if {@code k == n} an iterator containing [0, ..., n - 1] is returned.
-     *
      * @param n Size of the set from which subsets are selected.
      * @param k Size of the subsets to be enumerated.
-     * @param iterationOrder Specifies the {@link #iterator() iteration order}.
      * @throws IllegalArgumentException if {@code n < 0}.
      * @throws IllegalArgumentException if {@code k > n} or {@code k < 0}.
+     * @return a new instance.
      */
-    private Combinations(int n,
-                         int k,
-                         IterationOrder iterationOrder) {
-        BinomialCoefficient.checkBinomial(n, k);
-        this.n = n;
-        this.k = k;
-        this.iterationOrder = iterationOrder;
+    public static Combinations of(int n,
+                                  int k) {
+        return new Combinations(n, k);
     }
 
     /**
@@ -125,21 +79,40 @@ public class Combinations implements Iterable<int[]> {
         return k;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * Creates an iterator whose range is the k-element subsets of
+     * {0, ..., n - 1} represented as {@code int[]} arrays.
+     * <p>
+     * The iteration order is lexicographic: the arrays returned by the
+     * {@link #iterator() iterator} are sorted in descending order and
+     * they are visited in lexicographic order with significance from
+     * right to left.
+     * For example, {@code new Combinations(4, 2).iterator()} returns
+     * an iterator that will generate the following sequence of arrays
+     * on successive calls to
+     * {@code next()}:<br>
+     * {@code [0, 1], [0, 2], [1, 2], [0, 3], [1, 3], [2, 3]}
+     * </p>
+     * If {@code k == 0} an iterator containing an empty array is returned;
+     * if {@code k == n} an iterator containing [0, ..., n - 1] is returned.
+     */
     @Override
     public Iterator<int[]> iterator() {
-        if (k == 0 ||
-            k == n) {
-            return new SingletonIterator(k);
-        }
+        return k == 0 || k == n ?
+            new SingletonIterator(k) :
+            new LexicographicIterator(n, k);
+    }
 
-        switch (iterationOrder) {
-        case LEXICOGRAPHIC:
-            return new LexicographicIterator(n, k);
-        default:
-            // Should never happen.
-            throw new UnsupportedOperationException("Please file a bug 
report");
-        }
+    /**
+     * Creates a comparator.
+     * When performing a comparison, if an element of the array is not
+     * within the interval [0, {@code n}), an {@code IllegalArgumentException}
+     * will be thrown.
+     *
+     * @return a comparator.
+     */
+    public Comparator<int[]> comparator() {
+        return new LexicographicComparator(n, k);
     }
 
     /**
@@ -153,7 +126,6 @@ public class Combinations implements Iterable<int[]> {
      * implementation.  If constructor arguments satisfy {@code k == 0}
      * or {@code k >= n}, no exception is generated, but the iterator is empty.
      * </p>
-     *
      */
     private static class LexicographicIterator implements Iterator<int[]> {
         /** Size of subsets returned by the iterator. */
@@ -330,10 +302,8 @@ public class Combinations implements Iterable<int[]> {
      * The comparison is based on the value (in base 10) represented
      * by the digit (interpreted in base {@code n}) in the input array,
      * in reverse order.
-     * For example if {@code c} is {@code {3, 2, 1}}, and {@code n}
-     * is 3, the method will return 18.
      */
-    public static class LexicographicComparator
+    private static class LexicographicComparator
         implements Comparator<int[]>,
                    Serializable {
         /** Serializable version identifier. */
@@ -347,31 +317,13 @@ public class Combinations implements Iterable<int[]> {
          * @param n Size of the set from which subsets are selected.
          * @param k Size of the subsets to be enumerated.
          */
-        public LexicographicComparator(int n,
-                                       int k) {
+        LexicographicComparator(int n,
+                                int k) {
             this.n = n;
             this.k = k;
         }
 
         /**
-         * Gets the size of the set from which combinations are drawn.
-         *
-         * @return the size of the universe.
-         */
-        public int getN() {
-            return n;
-        }
-
-        /**
-         * Gets the number of elements in each combination.
-         *
-         * @return the size of the subsets.
-         */
-        public int getK() {
-            return k;
-        }
-
-        /**
          * {@inheritDoc}
          *
          * @throws IllegalArgumentException if the array lengths are not
@@ -411,6 +363,8 @@ public class Combinations implements Iterable<int[]> {
          * Computes the value (in base 10) represented by the digit
          * (interpreted in base {@code n}) in the input array in reverse
          * order.
+         * For example if {@code c} is {@code {3, 2, 1}}, and {@code n}
+         * is 3, the method will return 18.
          *
          * @param c Input array.
          * @return the lexicographic norm.
diff --git 
a/commons-numbers-combinatorics/src/test/java/org/apache/commons/numbers/combinatorics/CombinationsTest.java
 
b/commons-numbers-combinatorics/src/test/java/org/apache/commons/numbers/combinatorics/CombinationsTest.java
index 0b768c2..3e5febf 100644
--- 
a/commons-numbers-combinatorics/src/test/java/org/apache/commons/numbers/combinatorics/CombinationsTest.java
+++ 
b/commons-numbers-combinatorics/src/test/java/org/apache/commons/numbers/combinatorics/CombinationsTest.java
@@ -27,93 +27,84 @@ import org.junit.jupiter.api.Test;
  */
 public class CombinationsTest {
     @Test
-    public void testAccessor1() {
+    public void testGetN() {
         final int n = 5;
         final int k = 3;
-        Assertions.assertEquals(n, new Combinations(n, k).getN());
+        Assertions.assertEquals(n, Combinations.of(n, k).getN());
     }
+
     @Test
-    public void testAccessor2() {
+    public void testGetK() {
         final int n = 5;
         final int k = 3;
-        Assertions.assertEquals(k, new Combinations(n, k).getK());
+        Assertions.assertEquals(k, Combinations.of(n, k).getK());
     }
 
     @Test
     public void testLexicographicIterator() {
-        checkLexicographicIterator(new Combinations.LexicographicComparator(5, 
3));
-        checkLexicographicIterator(new Combinations.LexicographicComparator(6, 
4));
-        checkLexicographicIterator(new Combinations.LexicographicComparator(8, 
2));
-        checkLexicographicIterator(new Combinations.LexicographicComparator(6, 
1));
-        checkLexicographicIterator(new Combinations.LexicographicComparator(3, 
3));
-        checkLexicographicIterator(new Combinations.LexicographicComparator(1, 
1));
-        checkLexicographicIterator(new Combinations.LexicographicComparator(1, 
0));
-        checkLexicographicIterator(new Combinations.LexicographicComparator(0, 
0));
-        checkLexicographicIterator(new Combinations.LexicographicComparator(4, 
2));
-        checkLexicographicIterator(new 
Combinations.LexicographicComparator(123, 2));
+        checkLexicographicIterator(5, 3);
+        checkLexicographicIterator(6, 4);
+        checkLexicographicIterator(8, 2);
+        checkLexicographicIterator(6, 1);
+        checkLexicographicIterator(3, 3);
+        checkLexicographicIterator(1, 1);
+        checkLexicographicIterator(1, 0);
+        checkLexicographicIterator(0, 0);
+        checkLexicographicIterator(4, 2);
+        checkLexicographicIterator(123, 2);
     }
 
     @Test
     public void testLexicographicComparatorWrongIterate1() {
         final int n = 5;
         final int k = 3;
-        final Comparator<int[]> comp = new 
Combinations.LexicographicComparator(n, k);
+        final Comparator<int[]> comp = Combinations.of(n, k).comparator();
         Assertions.assertThrows(IllegalArgumentException.class,
-                () -> comp.compare(new int[] {1}, new int[] {0, 1, 2})
-        );
+                                () -> comp.compare(new int[] {1},
+                                                   new int[] {0, 1, 2}));
     }
 
     @Test
     public void testLexicographicComparatorWrongIterate2() {
         final int n = 5;
         final int k = 3;
-        final Comparator<int[]> comp = new 
Combinations.LexicographicComparator(n, k);
+        final Comparator<int[]> comp = Combinations.of(n, k).comparator();
         Assertions.assertThrows(IllegalArgumentException.class,
-                () -> comp.compare(new int[] {0, 1, 2}, new int[] {0, 1, 2, 3})
-        );
+                                () -> comp.compare(new int[] {0, 1, 2},
+                                                   new int[] {0, 1, 2, 3}));
     }
 
     @Test
     public void testLexicographicComparatorWrongIterate3() {
         final int n = 5;
         final int k = 3;
-        final Comparator<int[]> comp = new 
Combinations.LexicographicComparator(n, k);
+           final Comparator<int[]> comp = Combinations.of(n, k).comparator();
         Assertions.assertThrows(IllegalArgumentException.class,
-                () -> comp.compare(new int[] {1, 2, 5}, new int[] {0, 1, 2})
-        );
+                                () -> comp.compare(new int[] {1, 2, 5},
+                                                   new int[] {0, 1, 2}));
     }
 
     @Test
     public void testLexicographicComparatorWrongIterate4() {
         final int n = 5;
         final int k = 3;
-        final Comparator<int[]> comp = new 
Combinations.LexicographicComparator(n, k);
+        final Comparator<int[]> comp = Combinations.of(n, k).comparator();
         Assertions.assertThrows(IllegalArgumentException.class,
-                () -> comp.compare(new int[] {1, 2, 4}, new int[] {-1, 1, 2})
-        );
-    }
-
-    @Test
-    public void testLexicographicComparatorAccessors() {
-        final int n = 9;
-        final int k = 6;
-        final Combinations.LexicographicComparator comp =
-            new Combinations.LexicographicComparator(n, k);
-        Assertions.assertEquals(n, comp.getN());
-        Assertions.assertEquals(k, comp.getK());
+                                () -> comp.compare(new int[] {1, 2, 4},
+                                                   new int[] {-1, 1, 2}));
     }
 
     @Test
     public void testLexicographicComparator() {
         final int n = 5;
         final int k = 3;
-        final Comparator<int[]> comp = new 
Combinations.LexicographicComparator(n, k);
+        final Comparator<int[]> comp = Combinations.of(n, k).comparator();
         Assertions.assertEquals(1, comp.compare(new int[] {1, 2, 4},
-                                            new int[] {1, 2, 3}));
+                                                new int[] {1, 2, 3}));
         Assertions.assertEquals(-1, comp.compare(new int[] {0, 1, 4},
-                                             new int[] {0, 2, 4}));
+                                                 new int[] {0, 2, 4}));
         Assertions.assertEquals(0, comp.compare(new int[] {1, 3, 4},
-                                            new int[] {1, 3, 4}));
+                                                new int[] {1, 3, 4}));
     }
 
     /**
@@ -123,18 +114,18 @@ public class CombinationsTest {
     public void testLexicographicComparatorUnsorted() {
         final int n = 5;
         final int k = 3;
-        final Comparator<int[]> comp = new 
Combinations.LexicographicComparator(n, k);
+        final Comparator<int[]> comp = Combinations.of(n, k).comparator();
         Assertions.assertEquals(1, comp.compare(new int[] {1, 4, 2},
-                                            new int[] {1, 3, 2}));
+                                                new int[] {1, 3, 2}));
         Assertions.assertEquals(-1, comp.compare(new int[] {0, 4, 1},
-                                             new int[] {0, 4, 2}));
+                                                 new int[] {0, 4, 2}));
         Assertions.assertEquals(0, comp.compare(new int[] {1, 4, 3},
-                                            new int[] {1, 3, 4}));
+                                                new int[] {1, 3, 4}));
     }
 
     @Test
     public void testEmptyCombination() {
-        final Iterator<int[]> iter = new Combinations(12345, 0).iterator();
+        final Iterator<int[]> iter = Combinations.of(12345, 0).iterator();
         Assertions.assertTrue(iter.hasNext());
         final int[] c = iter.next();
         Assertions.assertEquals(0, c.length);
@@ -144,7 +135,7 @@ public class CombinationsTest {
     @Test
     public void testFullSetCombination() {
         final int n = 67;
-        final Iterator<int[]> iter = new Combinations(n, n).iterator();
+        final Iterator<int[]> iter = Combinations.of(n, n).iterator();
         Assertions.assertTrue(iter.hasNext());
         final int[] c = iter.next();
         Assertions.assertEquals(n, c.length);
@@ -161,16 +152,16 @@ public class CombinationsTest {
      * increasing sequence of b(n,k) arrays, each having length k
      * and each array itself increasing.
      *
-     * @param comp Comparator.
+     * @param n Size of the set from which subsets are selected.
+     * @param k Size of the subsets to be enumerated.
      */
-    private static void 
checkLexicographicIterator(Combinations.LexicographicComparator comp) {
-        final int n = comp.getN();
-        final int k = comp.getK();
-
+    private static void checkLexicographicIterator(int n,
+                                                   int k) {
         int[] lastIterate = null;
 
         long numIterates = 0;
-        for (int[] iterate : new Combinations(n, k)) {
+        final Comparator<int[]> comp = Combinations.of(n, k).comparator();
+        for (int[] iterate : Combinations.of(n, k)) {
             Assertions.assertEquals(k, iterate.length);
 
             // Check that the sequence of iterates is ordered.
@@ -192,15 +183,13 @@ public class CombinationsTest {
     }
 
     @Test
-    public void testCombinationsIteratorFail1() {
+    public void testCombinationsPrecondition1() {
         Assertions.assertThrows(IllegalArgumentException.class,
-                () -> new Combinations(4, 5).iterator()
-        );
+                                () -> Combinations.of(4, 5));
     }
     @Test
-    public void testCombinationsIteratorFail2() {
+    public void testCombinationsPrecondition2() {
         Assertions.assertThrows(IllegalArgumentException.class,
-                () -> new Combinations(-1, -2).iterator()
-        );
+                                () -> Combinations.of(-1, -2));
     }
 }

Reply via email to