diff --git a/src/main/java/org/libj/lang/Numbers.java b/src/main/java/org/libj/lang/Numbers.java index 09ee270..dea3a5e 100644 --- a/src/main/java/org/libj/lang/Numbers.java +++ b/src/main/java/org/libj/lang/Numbers.java @@ -2347,7 +2347,7 @@ public static N parseNumber(final String s, final Class as private static final String MIN_LONG = "-9223372036854775808"; private static final String MAX_LONG = "9223372036854775807"; - public static Number parseNumber(final String str) { + public static Number parseNumberWhole(final String str) { final int len; if (str == null || (len = str.length()) == 0) return null; @@ -2469,15 +2469,19 @@ public static N cast(final Number n, final Class as) { * * @param s The string to test. * @return {@code true} if the specified string represents a number, or a number with a fraction of two numbers. + * @see #isNumber(String) */ - public static boolean isNumber(String s) { - if (s == null || (s = s.trim()).length() == 0) + public static boolean isNumberWithFraction(String s) { + final int len; + if (s == null || (len = (s = s.trim()).length()) == 0) return false; - final String[] parts = Strings.split(s, ' '); - if (parts.length > 2) - return false; + int spaces = 0; + for (int i = 0; i < len; ++i) + if (s.charAt(i) == ' ' && ++spaces > 2) + return false; + final String[] parts = Strings.split(s, ' '); if (parts.length == 2) { final int slash = parts[1].indexOf('/'); if (slash < 0) @@ -2489,7 +2493,20 @@ public static boolean isNumber(String s) { return isNumber(parts[0], true); } - private static boolean isNumber(String s, final boolean isFraction) { + /** + * Tests whether the specified string represents a number. + *

+ * This method supports exponent form (i.e. {@code 3.2E-5}). + * + * @param s The string to test. + * @return {@code true} if the specified string represents a number. + * @see #isNumberWithFraction(String) + */ + public static boolean isNumber(String s) { + return isNumber(s, false); + } + + public static boolean isNumber(String s, final boolean isFraction) { final int len; if (s == null || (len = (s = s.trim()).length()) == 0) return false; @@ -2520,7 +2537,7 @@ else if (c == '-') { minusEncountered = true; } - else if (!expEncountered && c != '+') { + else if (c != '+') { return false; } } diff --git a/src/main/java/org/libj/lang/Strings.java b/src/main/java/org/libj/lang/Strings.java index 5e67bde..3bfee20 100644 --- a/src/main/java/org/libj/lang/Strings.java +++ b/src/main/java/org/libj/lang/Strings.java @@ -2653,26 +2653,24 @@ public static String intern(final String str) { } private static String[] split(final CharSequence s, final int i$, final char ch, final int empties, final StringBuilder b, int index, final int depth) { - final String[] parts; - final char c = s.charAt(index); - if (c != ch) { - b.append(c); - if (++index == i$) { - if (index != i$ || b.length() > 0) { - final String part = b.toString(); - parts = new String[depth + 1]; - parts[depth] = part; - } - else { - parts = new String[depth - empties]; - } - } - else { - parts = split(s, i$, ch, empties, b, index, depth); + while (true) { + final char c = s.charAt(index); + if (c != ch) { + b.append(c); + if (++index != i$) + continue; + + if (index == i$ && b.length() == 0) + return new String[depth - empties]; + + final String part = b.toString(); + final String[] parts = new String[depth + 1]; + parts[depth] = part; + return parts; } - } - else { + if (++index != i$ || b.length() > 0) { + final String[] parts; final String part = b.toString(); if (index == i$) parts = new String[depth + 1]; @@ -2680,16 +2678,14 @@ private static String[] split(final CharSequence s, final int i$, final char ch, parts = split(s, i$, ch, part.length() == 0 ? empties + 1 : 0, new StringBuilder(), index, depth + 1); parts[Math.min(parts.length - 1, depth)] = part; + return parts; } - else { - if (index == i$) - parts = new String[depth - empties]; - else - parts = split(s, i$, ch, empties, new StringBuilder(), index, depth); - } - } - return parts; + if (index == i$) + return new String[depth - empties]; + + return split(s, i$, ch, empties, new StringBuilder(), index, depth); + } } /** diff --git a/src/test/java/org/libj/lang/NumbersTest.java b/src/test/java/org/libj/lang/NumbersTest.java index 0c2ec00..949ea89 100644 --- a/src/test/java/org/libj/lang/NumbersTest.java +++ b/src/test/java/org/libj/lang/NumbersTest.java @@ -230,102 +230,102 @@ public void testShortOfBytes() { } @Test - public void testParseNumberByteMin() { + public void testParseNumberWholeByteMin() { final Byte v = Byte.MIN_VALUE; String s = v.toString(); - Number t = Numbers.parseNumber(s); + Number t = Numbers.parseNumberWhole(s); assertEquals(v, t); s = s.substring(0, s.length() - 1) + "9"; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(Short.valueOf(s), t); } @Test - public void testParseNumberByteMax() { + public void testParseNumberWholeByteMax() { final Byte v = Byte.MAX_VALUE; String s = v.toString(); - Number t = Numbers.parseNumber(s); + Number t = Numbers.parseNumberWhole(s); assertEquals(v, t); s = s.substring(0, s.length() - 1) + "8"; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(Short.valueOf(s), t); s = "+" + s; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(Short.valueOf(s), t); } @Test - public void testParseNumberShortMin() { + public void testParseNumberWholeShortMin() { final Short v = Short.MIN_VALUE; String s = v.toString(); - Number t = Numbers.parseNumber(s); + Number t = Numbers.parseNumberWhole(s); assertEquals(v, t); s = s.substring(0, s.length() - 1) + "9"; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(Integer.valueOf(s), t); } @Test - public void testParseNumberShortMax() { + public void testParseNumberWholeShortMax() { final Short v = Short.MAX_VALUE; String s = v.toString(); - Number t = Numbers.parseNumber(s); + Number t = Numbers.parseNumberWhole(s); assertEquals(v, t); s = s.substring(0, s.length() - 1) + "8"; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(Integer.valueOf(s), t); s = "+" + s; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(Integer.valueOf(s), t); } @Test - public void testParseNumberIntMin() { + public void testParseNumberWholeIntMin() { final Integer v = Integer.MIN_VALUE; String s = v.toString(); - Number t = Numbers.parseNumber(s); + Number t = Numbers.parseNumberWhole(s); assertEquals(v, t); s = s.substring(0, s.length() - 1) + "9"; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(Long.valueOf(s), t); } @Test - public void testParseNumberIntMax() { + public void testParseNumberWholeIntMax() { final Integer v = Integer.MAX_VALUE; String s = v.toString(); - Number t = Numbers.parseNumber(s); + Number t = Numbers.parseNumberWhole(s); assertEquals(v, t); s = s.substring(0, s.length() - 1) + "8"; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(Long.valueOf(s), t); s = "+" + s; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(Long.valueOf(s), t); } @Test - public void testParseNumberLongMin() { + public void testParseNumberWholeLongMin() { final Long v = Long.MIN_VALUE; String s = v.toString(); - Number t = Numbers.parseNumber(s); + Number t = Numbers.parseNumberWhole(s); assertEquals(v, t); s = s.substring(0, s.length() - 1) + "9"; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(new BigInteger(s), t); } @Test - public void testParseNumberLongMax() { + public void testParseNumberWholeLongMax() { final Long v = Long.MAX_VALUE; String s = v.toString(); - Number t = Numbers.parseNumber(s); + Number t = Numbers.parseNumberWhole(s); assertEquals(v, t); s = s.substring(0, s.length() - 1) + "8"; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(new BigInteger(s), t); s = "+" + s; - t = Numbers.parseNumber(s); + t = Numbers.parseNumberWhole(s); assertEquals(new BigInteger(s), t); } @@ -340,10 +340,10 @@ public void testIsNumber() { assertTrue(Numbers.isNumber(" -6.022E23")); assertTrue(Numbers.isNumber(" 6.626068E-34")); assertTrue(Numbers.isNumber("-6.626068E-34 ")); - assertTrue(Numbers.isNumber("-6.626068E-34 24/49")); + assertTrue(Numbers.isNumberWithFraction("-6.626068E-34 24/49")); assertTrue(Numbers.isNumber("-6.6991202137503775E+18")); assertTrue(Numbers.isNumber("-6.6991202137503775E-18")); - assertTrue(Numbers.isNumber("3/5")); + assertTrue(Numbers.isNumberWithFraction("3/5")); assertFalse(Numbers.isNumber(null)); assertFalse(Numbers.isNumber(""));