Skip to content

Commit fbd2be7

Browse files
authored
Merge pull request stleary#337 from johnjaylward/OptimizeOpt
Optimizes opt* functions
2 parents f2b642a + 757b6ed commit fbd2be7

2 files changed

Lines changed: 551 additions & 58 deletions

File tree

JSONArray.java

Lines changed: 219 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,50 @@ public double getDouble(int index) throws JSONException {
244244
return object instanceof Number ? ((Number) object).doubleValue()
245245
: Double.parseDouble((String) object);
246246
} catch (Exception e) {
247-
throw new JSONException("JSONArray[" + index + "] is not a number.");
247+
throw new JSONException("JSONArray[" + index + "] is not a number.", e);
248+
}
249+
}
250+
251+
/**
252+
* Get the float value associated with a key.
253+
*
254+
* @param index
255+
* The index must be between 0 and length() - 1.
256+
* @return The numeric value.
257+
* @throws JSONException
258+
* if the key is not found or if the value is not a Number
259+
* object and cannot be converted to a number.
260+
*/
261+
public float getFloat(int index) throws JSONException {
262+
Object object = this.get(index);
263+
try {
264+
return object instanceof Number ? ((Number) object).floatValue()
265+
: Float.parseFloat(object.toString());
266+
} catch (Exception e) {
267+
throw new JSONException("JSONArray[" + index
268+
+ "] is not a number.", e);
269+
}
270+
}
271+
272+
/**
273+
* Get the Number value associated with a key.
274+
*
275+
* @param index
276+
* The index must be between 0 and length() - 1.
277+
* @return The numeric value.
278+
* @throws JSONException
279+
* if the key is not found or if the value is not a Number
280+
* object and cannot be converted to a number.
281+
*/
282+
public Number getNumber(int index) throws JSONException {
283+
Object object = this.get(index);
284+
try {
285+
if (object instanceof Number) {
286+
return (Number)object;
287+
}
288+
return JSONObject.stringToNumber(object.toString());
289+
} catch (Exception e) {
290+
throw new JSONException("JSONArray[" + index + "] is not a number.", e);
248291
}
249292
}
250293

@@ -266,9 +309,8 @@ public <E extends Enum<E>> E getEnum(Class<E> clazz, int index) throws JSONExcep
266309
// JSONException should really take a throwable argument.
267310
// If it did, I would re-implement this with the Enum.valueOf
268311
// method and place any thrown exception in the JSONException
269-
throw new JSONException("JSONObject[" + JSONObject.quote(Integer.toString(index))
270-
+ "] is not an enum of type " + JSONObject.quote(clazz.getSimpleName())
271-
+ ".");
312+
throw new JSONException("JSONArray[" + index + "] is not an enum of type "
313+
+ JSONObject.quote(clazz.getSimpleName()) + ".");
272314
}
273315
return val;
274316
}
@@ -289,7 +331,7 @@ public BigDecimal getBigDecimal (int index) throws JSONException {
289331
return new BigDecimal(object.toString());
290332
} catch (Exception e) {
291333
throw new JSONException("JSONArray[" + index +
292-
"] could not convert to BigDecimal.");
334+
"] could not convert to BigDecimal.", e);
293335
}
294336
}
295337

@@ -309,7 +351,7 @@ public BigInteger getBigInteger (int index) throws JSONException {
309351
return new BigInteger(object.toString());
310352
} catch (Exception e) {
311353
throw new JSONException("JSONArray[" + index +
312-
"] could not convert to BigInteger.");
354+
"] could not convert to BigInteger.", e);
313355
}
314356
}
315357

@@ -328,7 +370,7 @@ public int getInt(int index) throws JSONException {
328370
return object instanceof Number ? ((Number) object).intValue()
329371
: Integer.parseInt((String) object);
330372
} catch (Exception e) {
331-
throw new JSONException("JSONArray[" + index + "] is not a number.");
373+
throw new JSONException("JSONArray[" + index + "] is not a number.", e);
332374
}
333375
}
334376

@@ -384,7 +426,7 @@ public long getLong(int index) throws JSONException {
384426
return object instanceof Number ? ((Number) object).longValue()
385427
: Long.parseLong((String) object);
386428
} catch (Exception e) {
387-
throw new JSONException("JSONArray[" + index + "] is not a number.");
429+
throw new JSONException("JSONArray[" + index + "] is not a number.", e);
388430
}
389431
}
390432

@@ -518,11 +560,63 @@ public double optDouble(int index) {
518560
* @return The value.
519561
*/
520562
public double optDouble(int index, double defaultValue) {
521-
try {
522-
return this.getDouble(index);
523-
} catch (Exception e) {
563+
Object val = this.opt(index);
564+
if (JSONObject.NULL.equals(val)) {
524565
return defaultValue;
525566
}
567+
if (val instanceof Number){
568+
return ((Number) val).doubleValue();
569+
}
570+
if (val instanceof String) {
571+
try {
572+
return Double.parseDouble((String) val);
573+
} catch (Exception e) {
574+
return defaultValue;
575+
}
576+
}
577+
return defaultValue;
578+
}
579+
580+
/**
581+
* Get the optional float value associated with an index. NaN is returned
582+
* if there is no value for the index, or if the value is not a number and
583+
* cannot be converted to a number.
584+
*
585+
* @param index
586+
* The index must be between 0 and length() - 1.
587+
* @return The value.
588+
*/
589+
public float optFloat(int index) {
590+
return this.optFloat(index, Float.NaN);
591+
}
592+
593+
/**
594+
* Get the optional float value associated with an index. The defaultValue
595+
* is returned if there is no value for the index, or if the value is not a
596+
* number and cannot be converted to a number.
597+
*
598+
* @param index
599+
* subscript
600+
* @param defaultValue
601+
* The default value.
602+
* @return The value.
603+
*/
604+
public float optFloat(int index, float defaultValue) {
605+
Object val = this.opt(index);
606+
if (JSONObject.NULL.equals(val)) {
607+
return defaultValue;
608+
}
609+
if (val instanceof Number){
610+
return ((Number) val).floatValue();
611+
}
612+
if (val instanceof String) {
613+
try {
614+
return Float.parseFloat((String) val);
615+
} catch (Exception e) {
616+
return defaultValue;
617+
}
618+
}
619+
return defaultValue;
526620
}
527621

528622
/**
@@ -550,11 +644,22 @@ public int optInt(int index) {
550644
* @return The value.
551645
*/
552646
public int optInt(int index, int defaultValue) {
553-
try {
554-
return this.getInt(index);
555-
} catch (Exception e) {
647+
Object val = this.opt(index);
648+
if (JSONObject.NULL.equals(val)) {
556649
return defaultValue;
557650
}
651+
if (val instanceof Number){
652+
return ((Number) val).intValue();
653+
}
654+
655+
if (val instanceof String) {
656+
try {
657+
return new BigDecimal(val.toString()).intValue();
658+
} catch (Exception e) {
659+
return defaultValue;
660+
}
661+
}
662+
return defaultValue;
558663
}
559664

560665
/**
@@ -615,8 +720,29 @@ public <E extends Enum<E>> E optEnum(Class<E> clazz, int index, E defaultValue)
615720
* @return The value.
616721
*/
617722
public BigInteger optBigInteger(int index, BigInteger defaultValue) {
723+
Object val = this.opt(index);
724+
if (JSONObject.NULL.equals(val)) {
725+
return defaultValue;
726+
}
727+
if (val instanceof BigInteger){
728+
return (BigInteger) val;
729+
}
730+
if (val instanceof BigDecimal){
731+
return ((BigDecimal) val).toBigInteger();
732+
}
733+
if (val instanceof Double || val instanceof Float){
734+
return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
735+
}
736+
if (val instanceof Long || val instanceof Integer
737+
|| val instanceof Short || val instanceof Byte){
738+
return BigInteger.valueOf(((Number) val).longValue());
739+
}
618740
try {
619-
return this.getBigInteger(index);
741+
final String valStr = val.toString();
742+
if(JSONObject.isDecimalNotation(valStr)) {
743+
return new BigDecimal(valStr).toBigInteger();
744+
}
745+
return new BigInteger(valStr);
620746
} catch (Exception e) {
621747
return defaultValue;
622748
}
@@ -634,8 +760,25 @@ public BigInteger optBigInteger(int index, BigInteger defaultValue) {
634760
* @return The value.
635761
*/
636762
public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
763+
Object val = this.opt(index);
764+
if (JSONObject.NULL.equals(val)) {
765+
return defaultValue;
766+
}
767+
if (val instanceof BigDecimal){
768+
return (BigDecimal) val;
769+
}
770+
if (val instanceof BigInteger){
771+
return new BigDecimal((BigInteger) val);
772+
}
773+
if (val instanceof Double || val instanceof Float){
774+
return new BigDecimal(((Number) val).doubleValue());
775+
}
776+
if (val instanceof Long || val instanceof Integer
777+
|| val instanceof Short || val instanceof Byte){
778+
return new BigDecimal(((Number) val).longValue());
779+
}
637780
try {
638-
return this.getBigDecimal(index);
781+
return new BigDecimal(val.toString());
639782
} catch (Exception e) {
640783
return defaultValue;
641784
}
@@ -693,17 +836,73 @@ public long optLong(int index) {
693836
* @return The value.
694837
*/
695838
public long optLong(int index, long defaultValue) {
696-
try {
697-
return this.getLong(index);
698-
} catch (Exception e) {
839+
Object val = this.opt(index);
840+
if (JSONObject.NULL.equals(val)) {
841+
return defaultValue;
842+
}
843+
if (val instanceof Number){
844+
return ((Number) val).longValue();
845+
}
846+
847+
if (val instanceof String) {
848+
try {
849+
return new BigDecimal(val.toString()).longValue();
850+
} catch (Exception e) {
851+
return defaultValue;
852+
}
853+
}
854+
return defaultValue;
855+
}
856+
857+
/**
858+
* Get an optional {@link Number} value associated with a key, or <code>null</code>
859+
* if there is no such key or if the value is not a number. If the value is a string,
860+
* an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
861+
* would be used in cases where type coercion of the number value is unwanted.
862+
*
863+
* @param index
864+
* The index must be between 0 and length() - 1.
865+
* @return An object which is the value.
866+
*/
867+
public Number optNumber(int index) {
868+
return this.optNumber(index, null);
869+
}
870+
871+
/**
872+
* Get an optional {@link Number} value associated with a key, or the default if there
873+
* is no such key or if the value is not a number. If the value is a string,
874+
* an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
875+
* would be used in cases where type coercion of the number value is unwanted.
876+
*
877+
* @param index
878+
* The index must be between 0 and length() - 1.
879+
* @param defaultValue
880+
* The default.
881+
* @return An object which is the value.
882+
*/
883+
public Number optNumber(int index, Number defaultValue) {
884+
Object val = this.opt(index);
885+
if (JSONObject.NULL.equals(val)) {
699886
return defaultValue;
700887
}
888+
if (val instanceof Number){
889+
return (Number) val;
890+
}
891+
892+
if (val instanceof String) {
893+
try {
894+
return JSONObject.stringToNumber((String) val);
895+
} catch (Exception e) {
896+
return defaultValue;
897+
}
898+
}
899+
return defaultValue;
701900
}
702901

703902
/**
704903
* Get the optional string value associated with an index. It returns an
705904
* empty string if there is no value at that index. If the value is not a
706-
* string and is not null, then it is coverted to a string.
905+
* string and is not null, then it is converted to a string.
707906
*
708907
* @param index
709908
* The index must be between 0 and length() - 1.

0 commit comments

Comments
 (0)