PARQUET-1750: Reduce Memory Usage of RowRanges Class (#735)

* PARQUET-1750: Reduce Memory Usage of RowRanges Class

* Remove pre-initialized size constructor and add List constructor

Co-authored-by: David Mollitor <dmollitor@apache.org>
diff --git a/parquet-column/src/main/java/org/apache/parquet/internal/filter2/columnindex/RowRanges.java b/parquet-column/src/main/java/org/apache/parquet/internal/filter2/columnindex/RowRanges.java
index 7753507..cf6a1ca 100644
--- a/parquet-column/src/main/java/org/apache/parquet/internal/filter2/columnindex/RowRanges.java
+++ b/parquet-column/src/main/java/org/apache/parquet/internal/filter2/columnindex/RowRanges.java
@@ -91,27 +91,50 @@
     }
   }
 
-  static final RowRanges EMPTY = new RowRanges();
+  static final RowRanges EMPTY = new RowRanges(Collections.emptyList());
 
-  /*
-   * Creates a new RowRanges object with the single range [0, rowCount - 1].
-   */
-  static RowRanges createSingle(long rowCount) {
-    RowRanges ranges = new RowRanges();
-    ranges.add(new Range(0, rowCount - 1));
-    return ranges;
+  private final List<Range> ranges;
+
+  private RowRanges() {
+    this(new ArrayList<>());
   }
 
-  /*
-   * Creates a new RowRanges object with the following ranges.
+  private RowRanges(Range range) {
+    this(Collections.singletonList(range));
+  }
+
+  private RowRanges(List<Range> ranges) {
+    this.ranges = ranges;
+  }
+
+  /**
+   * Creates an immutable RowRanges object with the single range [0, rowCount -
+   * 1].
+   *
+   * @param rowCount a single row count
+   * @return an immutable RowRanges
+   */
+  static RowRanges createSingle(long rowCount) {
+    return new RowRanges(new Range(0L, rowCount - 1L));
+  }
+
+  /**
+   * Creates a mutable RowRanges object with the following ranges:
+   * <pre>
    * [firstRowIndex[0], lastRowIndex[0]],
    * [firstRowIndex[1], lastRowIndex[1]],
    * ...,
    * [firstRowIndex[n], lastRowIndex[n]]
+   * </pre>
    * (See OffsetIndex.getFirstRowIndex and OffsetIndex.getLastRowIndex for details.)
    *
    * The union of the ranges are calculated so the result ranges always contain the disjunct ranges. See union for
    * details.
+   *
+   * @param rowCount row count
+   * @param pageIndexes pageIndexes
+   * @param offsetIndex offsetIndex
+   * @return a mutable RowRanges
    */
   static RowRanges create(long rowCount, PrimitiveIterator.OfInt pageIndexes, OffsetIndex offsetIndex) {
     RowRanges ranges = new RowRanges();
@@ -192,11 +215,6 @@
     return result;
   }
 
-  private final List<Range> ranges = new ArrayList<>();
-
-  private RowRanges() {
-  }
-
   /*
    * Adds a range to the end of the list of ranges. It maintains the disjunct ascending order(*) of the ranges by
    * trying to union the specified range to the last ranges in the list. The specified range shall be larger(*) than