1bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2008 The Guava Authors 3bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 4bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Licensed under the Apache License, Version 2.0 (the "License"); 5bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * you may not use this file except in compliance with the License. 6bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * You may obtain a copy of the License at 7bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 8bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * http://www.apache.org/licenses/LICENSE-2.0 9bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 10bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Unless required by applicable law or agreed to in writing, software 11bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * distributed under the License is distributed on an "AS IS" BASIS, 12bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * See the License for the specific language governing permissions and 14bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * limitations under the License. 15bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 16bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 17bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpackage com.google.common.primitives; 18bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkElementIndex; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkPositionIndexes; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.lang.Double.NEGATIVE_INFINITY; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.lang.Double.POSITIVE_INFINITY; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.Beta; 27bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport com.google.common.annotations.GwtCompatible; 287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtIncompatible; 290888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.base.Converter; 30bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 31bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.Serializable; 32bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.AbstractList; 33bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.Arrays; 34bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.Collection; 35bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.Collections; 36bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.Comparator; 37bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.List; 38bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.RandomAccess; 397dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.regex.Pattern; 407dd252788645e940eada959bdde927426e2531c9Paul Duffin 417dd252788645e940eada959bdde927426e2531c9Paul Duffinimport javax.annotation.Nullable; 42bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 43bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/** 44bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Static utility methods pertaining to {@code double} primitives, that are not 45bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * already found in either {@link Double} or {@link Arrays}. 46bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 477dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>See the Guava User Guide article on <a href= 487dd252788645e940eada959bdde927426e2531c9Paul Duffin * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained"> 497dd252788645e940eada959bdde927426e2531c9Paul Duffin * primitive utilities</a>. 507dd252788645e940eada959bdde927426e2531c9Paul Duffin * 51bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @author Kevin Bourrillion 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 1.0 53bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 547dd252788645e940eada959bdde927426e2531c9Paul Duffin@GwtCompatible(emulated = true) 55bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic final class Doubles { 56bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private Doubles() {} 57bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 58bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The number of bytes required to represent a primitive {@code double} 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * value. 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static final int BYTES = Double.SIZE / Byte.SIZE; 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 67bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a hash code for {@code value}; equal to the result of invoking 68bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code ((Double) value).hashCode()}. 69bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 70bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param value a primitive {@code double} value 71bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return a hash code for the value 72bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 73bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static int hashCode(double value) { 74bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return ((Double) value).hashCode(); 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(kevinb): do it this way when we can (GWT problem): 76bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // long bits = Double.doubleToLongBits(value); 770888a09821a98ac0680fad765217302858e70fa4Paul Duffin // return (int) (bits ^ (bits >>> 32)); 78bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 79bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 80bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 81bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Compares the two specified {@code double} values. The sign of the value 82bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * returned is the same as that of <code>((Double) a).{@linkplain 83bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Double#compareTo compareTo}(b)</code>. As with that method, {@code NaN} is 84bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * treated as greater than all other values, and {@code 0.0 > -0.0}. 85bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 860888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p><b>Note:</b> this method simply delegates to the JDK method {@link 870888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Double#compare}. It is provided for consistency with the other primitive 880888a09821a98ac0680fad765217302858e70fa4Paul Duffin * types, whose compare methods were not added to the JDK until JDK 7. 890888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 90bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param a the first {@code double} to compare 91bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param b the second {@code double} to compare 92bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return a negative value if {@code a} is less than {@code b}; a positive 93bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * value if {@code a} is greater than {@code b}; or zero if they are equal 94bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 95bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static int compare(double a, double b) { 96bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return Double.compare(a, b); 97bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 98bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 99bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns {@code true} if {@code value} represents a real number. This is 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * equivalent to, but not necessarily implemented as, 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code !(Double.isInfinite(value) || Double.isNaN(value))}. 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static boolean isFinite(double value) { 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return NEGATIVE_INFINITY < value & value < POSITIVE_INFINITY; 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 111bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns {@code true} if {@code target} is present as an element anywhere in 112bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code array}. Note that this always returns {@code false} when {@code 113bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * target} is {@code NaN}. 114bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 115bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param array an array of {@code double} values, possibly empty 116bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param target a primitive {@code double} value 117bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return {@code true} if {@code array[i] == target} for some value of {@code 118bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * i} 119bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 120bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static boolean contains(double[] array, double target) { 121bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (double value : array) { 122bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (value == target) { 123bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return true; 124bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 125bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 126bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return false; 127bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 128bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 129bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 130bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns the index of the first appearance of the value {@code target} in 131bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code array}. Note that this always returns {@code -1} when {@code target} 132bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * is {@code NaN}. 133bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 134bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param array an array of {@code double} values, possibly empty 135bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param target a primitive {@code double} value 136bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the least index {@code i} for which {@code array[i] == target}, or 137bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code -1} if no such index exists. 138bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 139bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static int indexOf(double[] array, double target) { 140bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return indexOf(array, target, 0, array.length); 141bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 142bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(kevinb): consider making this public 1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static int indexOf( 1450888a09821a98ac0680fad765217302858e70fa4Paul Duffin double[] array, double target, int start, int end) { 146bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = start; i < end; i++) { 147bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (array[i] == target) { 148bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return i; 149bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 150bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 151bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return -1; 152bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 153bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 154bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 155bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns the start position of the first occurrence of the specified {@code 156bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * target} within {@code array}, or {@code -1} if there is no such occurrence. 157bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 158bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>More formally, returns the lowest index {@code i} such that {@code 159bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly 160bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * the same elements as {@code target}. 161bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 162bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>Note that this always returns {@code -1} when {@code target} contains 163bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code NaN}. 164bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 165bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param array the array to search for the sequence {@code target} 166bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param target the array to search for as a sub-sequence of {@code array} 167bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 168bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static int indexOf(double[] array, double[] target) { 169bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkNotNull(array, "array"); 170bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkNotNull(target, "target"); 171bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (target.length == 0) { 172bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return 0; 173bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 174bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin outer: 1760888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (int i = 0; i < array.length - target.length + 1; i++) { 177bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int j = 0; j < target.length; j++) { 178bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (array[i + j] != target[j]) { 179bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor continue outer; 180bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 181bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 182bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return i; 183bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 184bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return -1; 185bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 186bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 187bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 188bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns the index of the last appearance of the value {@code target} in 189bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code array}. Note that this always returns {@code -1} when {@code target} 190bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * is {@code NaN}. 191bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 192bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param array an array of {@code double} values, possibly empty 193bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param target a primitive {@code double} value 194bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the greatest index {@code i} for which {@code array[i] == target}, 195bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * or {@code -1} if no such index exists. 196bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 197bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static int lastIndexOf(double[] array, double target) { 198bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return lastIndexOf(array, target, 0, array.length); 199bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 200bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(kevinb): consider making this public 2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static int lastIndexOf( 2030888a09821a98ac0680fad765217302858e70fa4Paul Duffin double[] array, double target, int start, int end) { 204bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = end - 1; i >= start; i--) { 205bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (array[i] == target) { 206bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return i; 207bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 208bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 209bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return -1; 210bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 211bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 212bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 213bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns the least value present in {@code array}, using the same rules of 214bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * comparison as {@link Math#min(double, double)}. 215bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 216bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param array a <i>nonempty</i> array of {@code double} values 217bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the value present in {@code array} that is less than or equal to 218bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * every other value in the array 219bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IllegalArgumentException if {@code array} is empty 220bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 221bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static double min(double... array) { 222bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkArgument(array.length > 0); 223bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor double min = array[0]; 224bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = 1; i < array.length; i++) { 225bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor min = Math.min(min, array[i]); 226bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 227bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return min; 228bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 229bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 230bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 231bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns the greatest value present in {@code array}, using the same rules 232bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * of comparison as {@link Math#max(double, double)}. 233bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 234bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param array a <i>nonempty</i> array of {@code double} values 235bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the value present in {@code array} that is greater than or equal to 236bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * every other value in the array 237bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IllegalArgumentException if {@code array} is empty 238bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 239bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static double max(double... array) { 240bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkArgument(array.length > 0); 241bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor double max = array[0]; 242bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = 1; i < array.length; i++) { 243bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor max = Math.max(max, array[i]); 244bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 245bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return max; 246bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 247bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 248bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 249bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns the values from each provided array combined into a single array. 250bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * For example, {@code concat(new double[] {a, b}, new double[] {}, new 251bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * double[] {c}} returns the array {@code {a, b, c}}. 252bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 253bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param arrays zero or more {@code double} arrays 254bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return a single array containing all the values from the source arrays, in 255bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * order 256bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 257bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static double[] concat(double[]... arrays) { 258bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int length = 0; 259bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (double[] array : arrays) { 260bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor length += array.length; 261bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 262bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor double[] result = new double[length]; 263bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int pos = 0; 264bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (double[] array : arrays) { 265bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor System.arraycopy(array, 0, result, pos, array.length); 266bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor pos += array.length; 267bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 268bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 269bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 270bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 2710888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static final class DoubleConverter 2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin extends Converter<String, Double> implements Serializable { 2730888a09821a98ac0680fad765217302858e70fa4Paul Duffin static final DoubleConverter INSTANCE = new DoubleConverter(); 2740888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2750888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2760888a09821a98ac0680fad765217302858e70fa4Paul Duffin protected Double doForward(String value) { 2770888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Double.valueOf(value); 2780888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2790888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2800888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2810888a09821a98ac0680fad765217302858e70fa4Paul Duffin protected String doBackward(Double value) { 2820888a09821a98ac0680fad765217302858e70fa4Paul Duffin return value.toString(); 2830888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2840888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2850888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2860888a09821a98ac0680fad765217302858e70fa4Paul Duffin public String toString() { 2870888a09821a98ac0680fad765217302858e70fa4Paul Duffin return "Doubles.stringConverter()"; 2880888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2890888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2900888a09821a98ac0680fad765217302858e70fa4Paul Duffin private Object readResolve() { 2910888a09821a98ac0680fad765217302858e70fa4Paul Duffin return INSTANCE; 2920888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2930888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static final long serialVersionUID = 1; 2940888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2950888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2960888a09821a98ac0680fad765217302858e70fa4Paul Duffin /** 2970888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Returns a serializable converter object that converts between strings and 2980888a09821a98ac0680fad765217302858e70fa4Paul Duffin * doubles using {@link Double#valueOf} and {@link Double#toString()}. 2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin * 3000888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @since 16.0 3010888a09821a98ac0680fad765217302858e70fa4Paul Duffin */ 3020888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Beta 3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static Converter<String, Double> stringConverter() { 3040888a09821a98ac0680fad765217302858e70fa4Paul Duffin return DoubleConverter.INSTANCE; 3050888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3060888a09821a98ac0680fad765217302858e70fa4Paul Duffin 307bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 308bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns an array containing the same values as {@code array}, but 309bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * guaranteed to be of a specified minimum length. If {@code array} already 310bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * has a length of at least {@code minLength}, it is returned directly. 311bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Otherwise, a new array of size {@code minLength + padding} is returned, 312bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * containing the values of {@code array}, and zeroes in the remaining places. 313bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 314bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param array the source array 315bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param minLength the minimum length the returned array must guarantee 316bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param padding an extra amount to "grow" the array by if growth is 317bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * necessary 318bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IllegalArgumentException if {@code minLength} or {@code padding} is 319bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * negative 320bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return an array containing the values of {@code array}, with guaranteed 321bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * minimum length {@code minLength} 322bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 3230888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static double[] ensureCapacity( 3240888a09821a98ac0680fad765217302858e70fa4Paul Duffin double[] array, int minLength, int padding) { 325bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkArgument(minLength >= 0, "Invalid minLength: %s", minLength); 326bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkArgument(padding >= 0, "Invalid padding: %s", padding); 3270888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (array.length < minLength) 3280888a09821a98ac0680fad765217302858e70fa4Paul Duffin ? copyOf(array, minLength + padding) 3290888a09821a98ac0680fad765217302858e70fa4Paul Duffin : array; 330bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 331bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 332bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // Arrays.copyOf() requires Java 6 333bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private static double[] copyOf(double[] original, int length) { 334bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor double[] copy = new double[length]; 335bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor System.arraycopy(original, 0, copy, 0, Math.min(original.length, length)); 336bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return copy; 337bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 338bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 339bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 340bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a string containing the supplied {@code double} values, converted 341bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * to strings as specified by {@link Double#toString(double)}, and separated 342bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * by {@code separator}. For example, {@code join("-", 1.0, 2.0, 3.0)} returns 343bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * the string {@code "1.0-2.0-3.0"}. 344bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that {@link Double#toString(double)} formats {@code double} 3467dd252788645e940eada959bdde927426e2531c9Paul Duffin * differently in GWT sometimes. In the previous example, it returns the 3477dd252788645e940eada959bdde927426e2531c9Paul Duffin * string {@code "1-2-3"}. 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 349bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param separator the text that should appear between consecutive values in 350bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * the resulting string (but not at the start or end) 351bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param array an array of {@code double} values, possibly empty 352bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 353bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static String join(String separator, double... array) { 354bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkNotNull(separator); 355bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (array.length == 0) { 356bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return ""; 357bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 358bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 359bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // For pre-sizing a builder, just get the right order of magnitude 360bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor StringBuilder builder = new StringBuilder(array.length * 12); 361bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor builder.append(array[0]); 362bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = 1; i < array.length; i++) { 363bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor builder.append(separator).append(array[i]); 364bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 365bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return builder.toString(); 366bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 367bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 368bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 369bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a comparator that compares two {@code double} arrays 370bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * lexicographically. That is, it compares, using {@link 371bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * #compare(double, double)}), the first pair of values that follow any 372bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * common prefix, or when one array is a prefix of the other, treats the 373bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * shorter array as the lesser. For example, 374bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code [] < [1.0] < [1.0, 2.0] < [2.0]}. 375bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 376bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>The returned comparator is inconsistent with {@link 377bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Object#equals(Object)} (since arrays support only identity equality), but 378bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * it is consistent with {@link Arrays#equals(double[], double[])}. 379bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 380bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order"> 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Lexicographical order article at Wikipedia</a> 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 383bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 384bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static Comparator<double[]> lexicographicalComparator() { 385bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return LexicographicalComparator.INSTANCE; 386bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 387bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 388bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private enum LexicographicalComparator implements Comparator<double[]> { 389bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor INSTANCE; 390bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3910888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 392bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public int compare(double[] left, double[] right) { 393bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int minLength = Math.min(left.length, right.length); 394bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = 0; i < minLength; i++) { 395bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int result = Doubles.compare(left[i], right[i]); 396bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (result != 0) { 397bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 398bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 399bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 400bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return left.length - right.length; 401bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 402bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 403bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 404bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 4057dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns an array containing each value of {@code collection}, converted to 4067dd252788645e940eada959bdde927426e2531c9Paul Duffin * a {@code double} value in the manner of {@link Number#doubleValue}. 407bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 408bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>Elements are copied from the argument collection as if by {@code 409bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * collection.toArray()}. Calling this method is as thread-safe as calling 410bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * that method. 411bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 4127dd252788645e940eada959bdde927426e2531c9Paul Duffin * @param collection a collection of {@code Number} instances 413bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return an array containing the same values as {@code collection}, in the 414bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * same order, converted to primitives 415bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws NullPointerException if {@code collection} or any of its elements 416bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * is null 4177dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 1.0 (parameter was {@code Collection<Double>} before 12.0) 418bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 4197dd252788645e940eada959bdde927426e2531c9Paul Duffin public static double[] toArray(Collection<? extends Number> collection) { 420bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (collection instanceof DoubleArrayAsList) { 421bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return ((DoubleArrayAsList) collection).toDoubleArray(); 422bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 423bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 424bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Object[] boxedArray = collection.toArray(); 425bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int len = boxedArray.length; 426bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor double[] array = new double[len]; 427bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = 0; i < len; i++) { 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // checkNotNull for GWT (do not optimize) 4297dd252788645e940eada959bdde927426e2531c9Paul Duffin array[i] = ((Number) checkNotNull(boxedArray[i])).doubleValue(); 430bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 431bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return array; 432bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 433bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 434bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 435bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a fixed-size list backed by the specified array, similar to {@link 436bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)}, 437bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * but any attempt to set a value to {@code null} will result in a {@link 438bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * NullPointerException}. 439bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 440bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>The returned list maintains the values, but not the identities, of 441bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code Double} objects written to or read from it. For example, whether 442bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code list.get(0) == list.get(0)} is true for the returned list is 443bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * unspecified. 444bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 445bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>The returned list may have unexpected behavior if it contains {@code 446bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * NaN}, or if {@code NaN} is used as a parameter to any of its methods. 447bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 448bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param backingArray the array to back the list 449bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return a list view of the array 450bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 451bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static List<Double> asList(double... backingArray) { 452bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (backingArray.length == 0) { 453bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return Collections.emptyList(); 454bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 455bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new DoubleArrayAsList(backingArray); 456bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 457bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 458bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor @GwtCompatible 4590888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static class DoubleArrayAsList extends AbstractList<Double> 4600888a09821a98ac0680fad765217302858e70fa4Paul Duffin implements RandomAccess, Serializable { 461bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final double[] array; 462bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final int start; 463bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final int end; 464bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 465bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor DoubleArrayAsList(double[] array) { 466bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor this(array, 0, array.length); 467bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 468bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 469bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor DoubleArrayAsList(double[] array, int start, int end) { 470bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor this.array = array; 471bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor this.start = start; 472bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor this.end = end; 473bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 474bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4750888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int size() { 476bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return end - start; 477bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 478bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4790888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean isEmpty() { 480bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return false; 481bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 482bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4830888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Double get(int index) { 484bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkElementIndex(index, size()); 485bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return array[start + index]; 486bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 487bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4880888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean contains(Object target) { 489bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // Overridden to prevent a ton of boxing 490bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return (target instanceof Double) 491bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor && Doubles.indexOf(array, (Double) target, start, end) != -1; 492bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 493bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4940888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int indexOf(Object target) { 495bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // Overridden to prevent a ton of boxing 496bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (target instanceof Double) { 497bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int i = Doubles.indexOf(array, (Double) target, start, end); 498bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (i >= 0) { 499bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return i - start; 500bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 501bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 502bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return -1; 503bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 504bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5050888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int lastIndexOf(Object target) { 506bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // Overridden to prevent a ton of boxing 507bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (target instanceof Double) { 508bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int i = Doubles.lastIndexOf(array, (Double) target, start, end); 509bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (i >= 0) { 510bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return i - start; 511bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 512bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 513bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return -1; 514bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 515bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5160888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Double set(int index, Double element) { 517bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkElementIndex(index, size()); 518bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor double oldValue = array[start + index]; 5197dd252788645e940eada959bdde927426e2531c9Paul Duffin // checkNotNull for GWT (do not optimize) 5207dd252788645e940eada959bdde927426e2531c9Paul Duffin array[start + index] = checkNotNull(element); 521bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return oldValue; 522bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 523bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5240888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public List<Double> subList(int fromIndex, int toIndex) { 525bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int size = size(); 526bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checkPositionIndexes(fromIndex, toIndex, size); 527bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (fromIndex == toIndex) { 528bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return Collections.emptyList(); 529bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 530bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new DoubleArrayAsList(array, start + fromIndex, start + toIndex); 531bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 532bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5330888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean equals(Object object) { 534bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (object == this) { 535bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return true; 536bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 537bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (object instanceof DoubleArrayAsList) { 538bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor DoubleArrayAsList that = (DoubleArrayAsList) object; 539bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int size = size(); 540bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (that.size() != size) { 541bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return false; 542bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 543bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = 0; i < size; i++) { 544bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (array[start + i] != that.array[that.start + i]) { 545bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return false; 546bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 547bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 548bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return true; 549bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 550bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return super.equals(object); 551bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 552bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5530888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int hashCode() { 554bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int result = 1; 555bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = start; i < end; i++) { 556bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor result = 31 * result + Doubles.hashCode(array[i]); 557bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 558bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 559bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 560bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5610888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public String toString() { 562bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor StringBuilder builder = new StringBuilder(size() * 12); 563bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor builder.append('[').append(array[start]); 564bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor for (int i = start + 1; i < end; i++) { 565bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor builder.append(", ").append(array[i]); 566bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 567bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return builder.append(']').toString(); 568bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 569bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 570bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor double[] toDoubleArray() { 5717dd252788645e940eada959bdde927426e2531c9Paul Duffin // Arrays.copyOfRange() is not available under GWT 572bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int size = size(); 573bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor double[] result = new double[size]; 574bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor System.arraycopy(array, start, result, 0, size); 575bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 576bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 577bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 578bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private static final long serialVersionUID = 0; 579bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 5807dd252788645e940eada959bdde927426e2531c9Paul Duffin 5817dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 5827dd252788645e940eada959bdde927426e2531c9Paul Duffin * This is adapted from the regex suggested by {@link Double#valueOf(String)} 5837dd252788645e940eada959bdde927426e2531c9Paul Duffin * for prevalidating inputs. All valid inputs must pass this regex, but it's 5847dd252788645e940eada959bdde927426e2531c9Paul Duffin * semantically fine if not all inputs that pass this regex are valid -- 5857dd252788645e940eada959bdde927426e2531c9Paul Duffin * only a performance hit is incurred, not a semantics bug. 5867dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 5877dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("regular expressions") 5887dd252788645e940eada959bdde927426e2531c9Paul Duffin static final Pattern FLOATING_POINT_PATTERN = fpPattern(); 5897dd252788645e940eada959bdde927426e2531c9Paul Duffin 5907dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("regular expressions") 5917dd252788645e940eada959bdde927426e2531c9Paul Duffin private static Pattern fpPattern() { 5927dd252788645e940eada959bdde927426e2531c9Paul Duffin String decimal = "(?:\\d++(?:\\.\\d*+)?|\\.\\d++)"; 5937dd252788645e940eada959bdde927426e2531c9Paul Duffin String completeDec = decimal + "(?:[eE][+-]?\\d++)?[fFdD]?"; 5947dd252788645e940eada959bdde927426e2531c9Paul Duffin String hex = "(?:\\p{XDigit}++(?:\\.\\p{XDigit}*+)?|\\.\\p{XDigit}++)"; 5957dd252788645e940eada959bdde927426e2531c9Paul Duffin String completeHex = "0[xX]" + hex + "[pP][+-]?\\d++[fFdD]?"; 5967dd252788645e940eada959bdde927426e2531c9Paul Duffin String fpPattern = "[+-]?(?:NaN|Infinity|" + completeDec + "|" + completeHex + ")"; 5977dd252788645e940eada959bdde927426e2531c9Paul Duffin return Pattern.compile(fpPattern); 5987dd252788645e940eada959bdde927426e2531c9Paul Duffin } 5997dd252788645e940eada959bdde927426e2531c9Paul Duffin 6007dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 6017dd252788645e940eada959bdde927426e2531c9Paul Duffin * Parses the specified string as a double-precision floating point value. 6027dd252788645e940eada959bdde927426e2531c9Paul Duffin * The ASCII character {@code '-'} (<code>'\u002D'</code>) is recognized 6037dd252788645e940eada959bdde927426e2531c9Paul Duffin * as the minus sign. 6047dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6057dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>Unlike {@link Double#parseDouble(String)}, this method returns 6067dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code null} instead of throwing an exception if parsing fails. 6077dd252788645e940eada959bdde927426e2531c9Paul Duffin * Valid inputs are exactly those accepted by {@link Double#valueOf(String)}, 6087dd252788645e940eada959bdde927426e2531c9Paul Duffin * except that leading and trailing whitespace is not permitted. 6097dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6107dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>This implementation is likely to be faster than {@code 6117dd252788645e940eada959bdde927426e2531c9Paul Duffin * Double.parseDouble} if many failures are expected. 6127dd252788645e940eada959bdde927426e2531c9Paul Duffin * 6137dd252788645e940eada959bdde927426e2531c9Paul Duffin * @param string the string representation of a {@code double} value 6147dd252788645e940eada959bdde927426e2531c9Paul Duffin * @return the floating point value represented by {@code string}, or 6157dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code null} if {@code string} has a length of zero or cannot be 6167dd252788645e940eada959bdde927426e2531c9Paul Duffin * parsed as a {@code double} value 6177dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 14.0 6187dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 6197dd252788645e940eada959bdde927426e2531c9Paul Duffin @GwtIncompatible("regular expressions") 6207dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 6217dd252788645e940eada959bdde927426e2531c9Paul Duffin @Beta 6227dd252788645e940eada959bdde927426e2531c9Paul Duffin public static Double tryParse(String string) { 6237dd252788645e940eada959bdde927426e2531c9Paul Duffin if (FLOATING_POINT_PATTERN.matcher(string).matches()) { 6247dd252788645e940eada959bdde927426e2531c9Paul Duffin // TODO(user): could be potentially optimized, but only with 6257dd252788645e940eada959bdde927426e2531c9Paul Duffin // extensive testing 6267dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 6277dd252788645e940eada959bdde927426e2531c9Paul Duffin return Double.parseDouble(string); 6287dd252788645e940eada959bdde927426e2531c9Paul Duffin } catch (NumberFormatException e) { 6297dd252788645e940eada959bdde927426e2531c9Paul Duffin // Double.parseDouble has changed specs several times, so fall through 6307dd252788645e940eada959bdde927426e2531c9Paul Duffin // gracefully 6317dd252788645e940eada959bdde927426e2531c9Paul Duffin } 6327dd252788645e940eada959bdde927426e2531c9Paul Duffin } 6337dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 6347dd252788645e940eada959bdde927426e2531c9Paul Duffin } 635bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor} 636