Giannis
Giannis

Reputation: 121

Create JSON object dynamically

I am trying to create JSON object with the following format.

{
"tableID": 1,
"price": 53,
"payment": "cash",
"quantity": 3,
"products": [
    {
        "ID": 1,
        "quantity": 1
    },
    {
        "ID": 3,
        "quantity": 2
    }
]

}

  1. I know how to do this statically using JSONObject and JSONArray. But I need a more dynamic way cause the products array must be implemented so it has many objects not just 2.

  2. IS there a way to delete the contents of a JSONObject? eg I have the following JSONobject

    { "ID": 3, "quantity": 2 }

Could I somehow erase its values so i can reuse the object in an iteration?

Upvotes: 3

Views: 34094

Answers (6)

Teodor
Teodor

Reputation: 124

I've implemented a builder which is able to build/construct JSON objects dynamically, by importing different forms of key - value pairs and applying them on top of each other (see the below attached source as well as some unit tests for it). It can be easily extended if you need to.

The attached code is at its initial version which supports up to 3 forms of importing key-value pairs. The actual library is not published yet but it will be soon.

Related to your case, for example, you can build your JSON object like so (I've added more fields there just to demonstrate more ways of appending data):

System.out.println(
        JsonBuilder.of()
                .add("tableID", "1")
                .add("price", "53")
                .add("priceString", "\"53\"")
                .add("payment = \"cash\"")
                .add("quantity : 3")
                .add("products[0].ID = 1")
                .add("products[0].quantity", "1")
                .add("products[1].ID = 3")
                .add("products[1].quantity = 2")
                .add("products[4].boolean       =   true      ")
                .add("products[4].booleanString=\"true\"")
                .build()
                .toPrettyString()
);

, which results into the following output:

{
  "tableID": 1,
  "price": 53,
  "priceString": "53",
  "payment": "cash",
  "quantity": 3,
  "products": [
    {
      "ID": 1,
      "quantity": 1
    },
    {
      "ID": 3,
      "quantity": 2
    },
    null,
    null,
    {
      "boolean": true,
      "booleanString": "true"
    }
  ]
}

The JsonBuilder class

package com.me0x.builder;

import static java.util.Objects.requireNonNull;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.BigIntegerNode;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.fasterxml.jackson.databind.node.DecimalNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import lombok.EqualsAndHashCode;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;

/**
 * This class is not a thread safe one.
 *
 * @author Teodor MAMOLEA
 */
@Log4j2
@EqualsAndHashCode
public final class JsonBuilder {

    private static final Set<Character> KEY_VALUE_SEPARATORS = Set.of(':', '=');

    private static final String FIELD_NAME_ARRAY_INDEX_SEPARATOR = "[";

    private static final int FIELD_NAME_ARRAY_INDEX_SEPARATOR_LENGTH = FIELD_NAME_ARRAY_INDEX_SEPARATOR.length();

    private static final NullNode ARRAY_AUTO_FILL_VALUE = new NullNode() {
        // NOP
    };

    private static final String ROOT_OBJECT_NODE_NAME = "root";

    public static JsonBuilder of() {
        return of(new ObjectMapper());
    }

    public static JsonBuilder of(final ObjectMapper objectMapper) {
        return new JsonBuilder(objectMapper);
    }

    private static String[] splitKeyValueLine(final String line) {
        if (StringUtils.isBlank(line)) {
            throw new IllegalArgumentException("Invalid key-value line!");
        }

        final Integer separatorIndex = KEY_VALUE_SEPARATORS.stream()
                .map(line::indexOf)
                .filter(separatorCharacterIndex -> -1 != separatorCharacterIndex)
                .min(Integer::compareTo)
                .orElseThrow(() -> new IllegalArgumentException("Invalid key-value line!"));

        return new String[]{
                line.substring(0, separatorIndex).trim(),
                line.substring(separatorIndex + 1).trim()
        };
    }

    private static Iterator<String> compileJsonFieldName(final String path) {
        if (StringUtils.isEmpty(path)) {
            throw new IllegalArgumentException("Empty field path can not be interpreted!");
        }

        final String calibratedPath = ROOT_OBJECT_NODE_NAME + (path.startsWith(FIELD_NAME_ARRAY_INDEX_SEPARATOR) ? "" : ".") + path;
        final List<String> compiledPath = new LinkedList<>();

        Arrays.stream(calibratedPath.split("\\.")).forEach(fieldName -> {
            if (!fieldName.matches("^[0-9A-Za-z]+(\\[[0-9]+])?$")) {
                throw new IllegalArgumentException("Invalid field name!");
            }

            compiledPath.add(fieldName);
        });

        return compiledPath.iterator();
    }

    private static JsonNode compileJsonFieldValue(final String value) {
        final JsonNode compiledValue;

        if (StringUtils.isEmpty(value) || "null".equalsIgnoreCase(value)) {
            compiledValue = NullNode.getInstance();
        } else if (value.matches("^\".*\"$")) {
            compiledValue = new TextNode(value.substring(1, value.length() - 1));
        } else {
            if (value.equalsIgnoreCase("false")) {
                compiledValue = BooleanNode.getFalse();
            } else if (value.equalsIgnoreCase("true")) {
                compiledValue = BooleanNode.getTrue();
            } else if (value.matches("^[+-]?[0-9]+$")) {
                compiledValue = new BigIntegerNode(new BigInteger(value));
            } else {
                JsonNode temporaryCompiledValue;
                try {
                    temporaryCompiledValue = new DecimalNode(new BigDecimal(value));
                } catch (final Exception e) {
                    // TODO: Add the possibility to enabled/disable this exact behaviour at builder level!
                    log.debug("Unable to interpret the [{}] value as a big decimal one! Interpreting it as a text value instead.", value, e);
                    temporaryCompiledValue = new TextNode(value);
                }
                compiledValue = temporaryCompiledValue;
            }
        }

        return compiledValue;
    }

    private static boolean isUnset(final JsonNode jsonNode) {
        return null == jsonNode || ARRAY_AUTO_FILL_VALUE == jsonNode;
    }

    private static void fill(final ArrayNode arrayNode, final int targetedArrayIndex) {
        for (int i = arrayNode.size(); i <= targetedArrayIndex; i++) {
            arrayNode.add(ARRAY_AUTO_FILL_VALUE);
        }
    }

    private final ObjectMapper objectMapper;
    private final ObjectNode rootObjectNode;

    private JsonBuilder(final ObjectMapper objectMapper) {
        this.objectMapper = requireNonNull(objectMapper);

        rootObjectNode = this.objectMapper.createObjectNode();
    }

    private JsonBuilder(final ObjectMapper objectMapper, final ObjectNode rootObjectNode) {
        this.objectMapper = requireNonNull(objectMapper);
        this.rootObjectNode = requireNonNull(rootObjectNode);
    }

    /**
     * Add a key-value line into the current under construction json builder.
     *
     * @param line
     *         represents a key-value line which is composed of the following 3
     *         parts:
     *         * key
     *         * separator
     *         * value
     *         </p>
     *         The 'separator' part separates the 'key' and 'value' parts and
     *         can be one either ':' or '=' character. Any spaces around it are
     *         fully ignored which means that the values of the 'key' and
     *         'value' parts are trimmed.
     *         </p>
     *         For more details about the 'key' and 'value' parts see the @see
     *         section.
     *
     * @see #add(String, String)
     */
    public JsonBuilder add(final String line) {
        final String[] keyValue = splitKeyValueLine(StringUtils.trim(line));
        return add(keyValue[0], keyValue[1]);
    }

    /**
     * Add a key-value pair into the current under construction json builder.
     *
     * @param key
     *         see the @see section.
     * @param value
     *         defines a json value. String values are always wrapped by the
     *         double-quotes characters and follows the format represented by
     *         the following examples:
     *         * "word"
     *         * "the "magic" word"
     *         * "the 'magic' word"
     *         * ""magic" and 'magic'"
     *         * ""magic" and "magic""
     *         * "true"
     *         * "-13.45"
     *         * ""
     *         </p>
     *         The fully empty string value, the {@code null} one, as well as
     *         the 'null' string value which is not wrapped by the double-quotes
     *         characters, is interpreted as {@code null}.
     *         </p>
     *         The following case-insensitive values are interpreted as boolean
     *         values:
     *         * false
     *         * true
     *         </p>
     *         Numbers are represented as following:
     *         * -10
     *         * 0
     *         * +09.0
     *         * 123.450
     *         * -12e+10
     *         * 12.33E05
     *         </p>
     *         Any other value, which does not fit under none of the above
     *         formats, is automatically interpreted as a text one which means,
     *         there is no such a value which is interpreted as an invalid one.
     *
     * @see #add(String, JsonNode)
     */
    public JsonBuilder add(final String key, final String value) {
        return add(StringUtils.trim(key), compileJsonFieldValue(StringUtils.trim(value)));
    }

    /**
     * Add a key-value pair into the current under construction json builder.
     *
     * @param key
     *         defines a json filed by its full json path which follows the
     *         format represented by the following example:
     *         * field
     *         * [2].field
     *         * the.path[0].to.any[1].field
     *         * [3].the.path[2].to.any[3].array[4].index[5]
     *         </p>
     *         The negative values for arrays indexes are not allowed. If an
     *         array has the '3' and '6' indexes populated only then, all
     *         remaining indexes, like '0', '1', '2', '4' and '5', are populated
     *         with {@code null}.
     * @param value
     *         any value which has to be added under the mentioned key.
     */
    public JsonBuilder add(final String key, final JsonNode value) {
        addField(
                rootObjectNode,
                compileJsonFieldName(StringUtils.trim(key)),
                null == value ? NullNode.getInstance() : value.deepCopy() // TODO: Address the double copy issue!
        );

        return this;
    }

    /**
     * Returns a copy of current json builder. Any made change on the returned
     * instance of json builder is not applied on the instance of json builder
     * which was copied, and vice-versa.
     * Both instances of json builders can continue their construction phase
     * fully independently of each other, without any constraints.
     */
    public JsonBuilder copy() {
        return new JsonBuilder(objectMapper.copy(), rootObjectNode.deepCopy());
    }

    /**
     * Returns an instance of json node which represents the current state of
     * json builder. Any made change on the returned instance of json node is
     * not applied on the instance of builder which built it, and vice-versa.
     * The instance of json builder can continue its construction phase without
     * any constraints.
     * An empty builder returns the {@link NullNode} value.
     */
    public JsonNode build() {
        JsonNode builtJsonNode = rootObjectNode.deepCopy().get(ROOT_OBJECT_NODE_NAME);

        if (null == builtJsonNode) {
            builtJsonNode = NullNode.getInstance();
        } else {
            // TODO: Adjust the returned json node by replacing all existing
            //  references to ARRAY_AUTO_FILL_VALUE with NullNode!
        }

        return builtJsonNode;
    }

    private void addField(final ObjectNode previousNode, final Iterator<String> fieldPathIterator, final JsonNode value) {
        final String currentField = fieldPathIterator.next();
        final int fieldNameArrayIndexSeparatorIndex = currentField.indexOf(FIELD_NAME_ARRAY_INDEX_SEPARATOR);

        if (-1 != fieldNameArrayIndexSeparatorIndex) {
            addArrayField(previousNode, fieldPathIterator, currentField, fieldNameArrayIndexSeparatorIndex, value);
        } else {
            addObjectField(previousNode, fieldPathIterator, currentField, value);
        }
    }

    private void addArrayField(
            final ObjectNode previousNode,
            final Iterator<String> fieldPathIterator,
            final String currentField,
            final int fieldNameArrayIndexSeparatorIndex,
            final JsonNode value) {
        final String currentFieldName = currentField.substring(0, fieldNameArrayIndexSeparatorIndex);
        final int currentArrayIndex;

        try {
            currentArrayIndex = Integer.parseInt(
                    currentField.substring(
                            fieldNameArrayIndexSeparatorIndex + FIELD_NAME_ARRAY_INDEX_SEPARATOR_LENGTH,
                            currentField.length() - 1
                    )
            );
        } catch (final NumberFormatException e) {
            throw new IllegalArgumentException("Invalid array index!");
        }

        JsonNode currentNode = previousNode.get(currentFieldName);

        if (isUnset(currentNode)) {
            currentNode = objectMapper.createArrayNode();
            previousNode.set(currentFieldName, currentNode);
        } else if (!currentNode.isArray()) {
            throw new IllegalArgumentException("Invalid json node type!");
        }

        final ArrayNode currentArrayJsonNode = (ArrayNode) currentNode;

        if (fieldPathIterator.hasNext()) {
            final JsonNode nextNode = currentArrayJsonNode.get(currentArrayIndex);
            final ObjectNode nextObjectNode;

            if (isUnset(nextNode)) {
                fill(currentArrayJsonNode, currentArrayIndex);

                nextObjectNode = objectMapper.createObjectNode();
                currentArrayJsonNode.set(currentArrayIndex, nextObjectNode);
            } else {
                if (!nextNode.isObject()) {
                    throw new IllegalArgumentException("Field already exists!");
                }

                nextObjectNode = (ObjectNode) nextNode;
            }

            addField(nextObjectNode, fieldPathIterator, value);
        } else {
            fill(currentArrayJsonNode, currentArrayIndex);
            currentArrayJsonNode.set(currentArrayIndex, value);
        }
    }

    private void addObjectField(
            final ObjectNode previousNode,
            final Iterator<String> fieldPathIterator,
            final String currentFieldName,
            final JsonNode value) {
        JsonNode currentNode = previousNode.get(currentFieldName);

        if (fieldPathIterator.hasNext()) {
            if (isUnset(currentNode)) {
                currentNode = objectMapper.createObjectNode();
                previousNode.set(currentFieldName, currentNode);
            } else if (!currentNode.isObject()) {
                throw new IllegalArgumentException("Invalid json node type!");
            }

            addField((ObjectNode) currentNode, fieldPathIterator, value);
        } else {
            if (null != currentNode) {
                throw new IllegalArgumentException("Field already exists!");
            }

            previousNode.set(currentFieldName, value);
        }
    }
}

The JsonBuilder classes unit-tests

package com.me0x.builder.test.unit;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.NullNode;
import java.math.BigDecimal;
import java.math.BigInteger;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import com.me0x.builder.JsonBuilder;
import com.me0x.util.test.common.AssertUtils;

/**
 * @author Teodor MAMOLEA
 */
class JsonBuilderTestUnit {

    public static String[] invalidArrayFieldPaths() {
        return new String[]{
                "[",
                "]",
                "[[",
                "]]",
                "[[]",
                "[]]",
                "[a]",
                "[-2]",
                "[[2]]",
                "[+2]",
                "[ 5]",
                "[5 ]",
                "[.]",
                "[2][3]",
                "field[",
                "field]",
                "field[[",
                "field]]",
                "field[[]",
                "field[]]",
                "field[a]",
                "field[-2]",
                "field[[2]]",
                "field[+2]",
                "field[ 5]",
                "field[5 ]",
                "field[.]",
                "field[2][3]",
                "[field",
                "]field",
                "[[field",
                "]]field",
                "[[]field",
                "[]]field",
                "[a]field",
                "[-2]field",
                "[2]field",
                "[+2]field",
                "[ 5]field",
                "[5 ]field",
                "[.]field",
                "[2][3]field",
                "[2]field"
        };
    }

    public static String[] validArrayFieldPaths() {
        return new String[]{
                "[0]",
                "[3].field",
                "[3].field[4]",
                "[3].field[4].field",
                "[3].field[4].field[5]",
                "field[4]",
                "field[4].field",
                "field[4].field[5]"
        };
    }

    public static String[] marginalValues() {
        return new String[]{
                "\"",
                "  \"  ",
                "\"hello",
                "hello\"",
                "truee",
                "1 0",
                "10 e+05"
        };
    }

    public static String[] nullValues() {
        return new String[]{
                null,
                "",
                "    ",
                "null",
                "NULL",
                "NulL",
                "   null   "
        };
    }

    public static String[] textValues() {
        return new String[]{
                "\"\"",
                "\"    \"",
                "\"field with a \"magic\" value\"",
                "\"true\"",
                "\"-10\"",
                "\"20\"",
                "    \"20\"    ",
                "\"10e+05\""
        };
    }

    public static String[] booleanValues() {
        return new String[]{
                "true",
                "false",
                "TRUE",
                "FALSE",
                "TrUE",
                "FalSE",
                "   true   ",
                "   false   "
        };
    }

    public static String[] integerValues() {
        return new String[]{
                "-0",
                "0",
                "+0",
                "000",
                "-10",
                "-0010",
                "10",
                "+10",
                "+0010",
                "  -20  ",
                "  20  ",
                "  +20  ",
                "-100",
                "  -100  "
        };
    }

    public static String[] decimalValues() {
        return new String[]{
                "-0.0",
                "0.0",
                "+0.0",
                "000.0",
                "-10.1",
                "-0010.1",
                "10.1",
                "+10.1",
                "+0010.1",
                "  -20.1  ",
                "  20.1  ",
                "  +20.01  ",
                "-100.100",
                "  -100.1  ",
                " +15e+05 ",
                " -15E-05 ",
                " 15E05 "
        };
    }

    private JsonBuilder jsonBuilder;

    @BeforeEach
    void beforeEach() {
        jsonBuilder = JsonBuilder.of();
    }

    @Test
    void testBuildEmptyBuilder() {
        final JsonNode builtJsonNode = jsonBuilder.build();

        assertNotNull(builtJsonNode);
        assertSame(NullNode.getInstance(), builtJsonNode);
    }

    @ParameterizedTest
    @MethodSource("invalidArrayFieldPaths")
    void testAddLineWithInvalidArrayFieldPath(final String fieldPath) {
        AssertUtils.assertThrows(
                IllegalArgumentException.class,
                () -> jsonBuilder.add(fieldPath + " = \"\""),
                "Invalid field name!"
        );
    }

    @ParameterizedTest
    @MethodSource("validArrayFieldPaths")
    void testAddLineWithValidArrayFieldPath(final String fieldPath) {
        final JsonNode builtJsonNode = jsonBuilder.add(fieldPath + " = \"\"").build();

        assertNotNull(builtJsonNode);

        // TODO: Add additional asserts against expected field!
    }

    @ParameterizedTest
    @MethodSource("marginalValues")
    void testAddLineWithMarginalValue(final String value) {
        final JsonNode builtJsonNode = jsonBuilder.add("field = " + value).build();

        assertNotNull(builtJsonNode);

        final JsonNode fieldJsonNode = builtJsonNode.get("field");

        assertNotNull(fieldJsonNode);
        assertTrue(fieldJsonNode.isTextual());
        assertEquals(value.trim(), fieldJsonNode.textValue());
    }

    @ParameterizedTest
    @MethodSource("nullValues")
    void testAddLineWithNullValue(final String value) {
        final JsonNode builtJsonNode = jsonBuilder.add("field = " + value).build();

        assertNotNull(builtJsonNode);

        final JsonNode fieldJsonNode = builtJsonNode.get("field");

        assertNotNull(fieldJsonNode);
        assertTrue(fieldJsonNode.isNull());
    }

    @ParameterizedTest
    @MethodSource("textValues")
    void testAddLineWithTextValue(final String value) {
        final JsonNode builtJsonNode = jsonBuilder.add("field = " + value).build();

        assertNotNull(builtJsonNode);

        final JsonNode fieldJsonNode = builtJsonNode.get("field");

        assertNotNull(fieldJsonNode);
        assertTrue(fieldJsonNode.isTextual());
        assertEquals(value.trim(), String.format("\"%s\"", fieldJsonNode.textValue()));
    }

    @ParameterizedTest
    @MethodSource("booleanValues")
    void testAddLineWithBooleanValue(final String value) {
        final JsonNode builtJsonNode = jsonBuilder.add("field = " + value).build();

        assertNotNull(builtJsonNode);

        final JsonNode fieldJsonNode = builtJsonNode.get("field");

        assertNotNull(fieldJsonNode);
        assertTrue(fieldJsonNode.isBoolean());
        assertEquals(value.trim().toLowerCase(), "" + fieldJsonNode.booleanValue());
    }

    @ParameterizedTest
    @MethodSource("integerValues")
    void testAddLineWithIntegerValue(final String value) {
        final JsonNode builtJsonNode = jsonBuilder.add("field = " + value).build();

        assertNotNull(builtJsonNode);

        final JsonNode fieldJsonNode = builtJsonNode.get("field");

        assertNotNull(fieldJsonNode);
        assertTrue(fieldJsonNode.isBigInteger());
        assertEquals(new BigInteger(value.trim()), fieldJsonNode.bigIntegerValue());
    }

    @ParameterizedTest
    @MethodSource("decimalValues")
    void testAddLineWithDecimalValue(final String value) {
        final JsonNode builtJsonNode = jsonBuilder.add("field = " + value).build();

        assertNotNull(builtJsonNode);

        final JsonNode fieldJsonNode = builtJsonNode.get("field");

        assertNotNull(fieldJsonNode);
        assertTrue(fieldJsonNode.isBigDecimal());
        assertEquals(new BigDecimal(value.trim()), fieldJsonNode.decimalValue());
    }

}

Upvotes: 0

Mohamed Hussein
Mohamed Hussein

Reputation: 1

For the first question

You can use this website to create the java classes and it will create 2, one for the attributes (tableId...) and another one for the products and simply contain array of Products in the main class

For the second question

you can just ignore it products[0] and ignore products[1](Id:3)

Upvotes: 0

user7010102
user7010102

Reputation:

Try constructing your JSON data as a string:

String json = "{" +
            "\"tableID\": 1," +
            "\"price\": 53," +
            "\"payment\": \"cash\"," +
            "\"quantity\": 3," +
            "\"products\": [";

for (int i = 0; i < 100; i++) {
    json += "{ \"ID\": 3, \"quantity\": 2 }";
    if(i != 100) json += ",";    
}

json += "]}";

and then create your JSONObject:

JSONObject jsonObject = new JSONObject(json);

I do not know what you exactly want to do, but I am guessing it is something like below:

for(int i = 0; i < products.size(); i++) {
    json += "{" +
          "\"ID\": " + products.get(i).getId() + "," +
          "\"quantity\": " + products.get(i).getQuantity() + " }";
    if(i != products.size() - 1) json += ",";
}

Note: See kws's answer for a more readable way to do it.

Upvotes: 0

pashute
pashute

Reputation: 4063

Woops, I wrote a whole long answer in js instead of java.

Simply use a HashMap and the GSON library from Google.

See here: How can I convert JSON to a HashMap using Gson?

You create your object dynamically as a hashMap, adding products and removing them at will. Then you turn the object into a JSON string with toJson() method.

(or start from any JSON string read into a HashMap with fromJson() and then manipulate it at will and return it to a string.

Upvotes: 0

kws
kws

Reputation: 966

To your first question, you can build the above json dynamically like this.

JSONObject jsonObject = new JSONObject();
jsonObject.put("tableID", 1);
jsonObject.put("price", 53);
jsonObject.put("payment", "cash");
jsonObject.put("quantity", 3);

JSONArray products = new JSONArray();

//product1
JSONObject product1 = new JSONObject();
product1.put("ID", 1);
product1.put("quantity", 1);
products.put(product1); //add to products

//product3
JSONObject product3 = new JSONObject();
product3.put("ID", 3);
product3.put("quantity", 2);
products.put(product3); //add to products

jsonObject.put("products", products); //add products array to the top-level json object

To the second question, you can remove an element of a JSONObject if you know its name.

jsonObject.remove("tableID"); // remove the tableID key/value pair

Or if you want to remove a specific element of a JSONArray then you have to know its position in the collection

jsonObject.getJSONArray("products").remove(1); //removes the second item in the collection which is the product3

Upvotes: 5

VIX
VIX

Reputation: 624

Yes, being an object you can change its content. Answering your question, it would be so.

JSONArray jsArray = (JSONArray) json.get("products");

JSONObject js1 = jsArray.getJSONObject(0);
System.out.println("0: "+js1);
jsArray.remove(0);

JSONObject js2 = jsArray.getJSONObject(0);
System.out.println("1: "+js2);
jsArray.remove(0);

Therefore, you can iterate that array or make it into a list, according to your preference

Upvotes: 0

Related Questions