1

How can I get sorted value on basis of cost variable in ascending or descending order for product node? Or how can I modify the value of the product node by sorting it in the below JsonNode response?

JsonNode response:

{
    "products": [
        {
            "Name": "Marble",
            "cost": 47.49
        },
        {
            "Name": "Mixer",
            "cost": 59.99
        },
        {
            "Name": "Soap",
            "cost": 3.99
        }
    ],
    "details": [
        {
            "area": 1090.098
        }
    ]
}

Excepted Response for descending:

{
    "products": [
        {
            "Name": "Mixer",
            "cost": 59.99
        },
        {
            "Name": "Marble",
            "cost": 47.49
        },
        {
            "Name": "Soap",
            "cost": 3.99
        }
    ],
    "details": [
        {
            "area": 1090.098
        }
    ]
}

Please guide me with proper solution, I am tired using comparator<> but this product node in JsonNode response does not have any POJO class so I can't use obj.StringName to compare.

0

2 Answers 2

1

The following solution uses the package javax.json.* for parsing and generating the JSON.

import java.util.*;
import java.io.*;
import javax.json.*;

public class Products
{
    // This is an "internal" method that loads the JSON to a String
    static final String json = LFEC.loadFile("products.json");
    
    public static void main(String[] argv) throws IOException
    {
        // *********** Parse Input Json *****************
        // Save the products in a sorted TreeMap...
        // NOTE: We will have to "resort it" afterwards..
        // **********************************************
        TreeMap<String, Double> productsSortedByName = new TreeMap<>();

        // Retrieve the JsonObject's
        JsonObject   obj         = Json.createReader(new StringReader(json)).readObject();
        JsonArray    products    = obj.getJsonArray("products");
        
        for (JsonObject product : products.getValuesAs(JsonObject.class))
        {
            // Retreives the product name and price for each product
            String name = product.getString("Name");
            double cost = product.getJsonNumber("cost").doubleValue();

            // Save in a Java TreeMap<String, Double> 
            // NOTE:  TreeMap sorts by the "Key" (not the value)

            productsSortedByName.put(name, Double.valueOf(cost));
        }
        
        // ******** Sort Products by Price **************
        // Since the question requires that the TreeMap sort by price, not product name...
        // This shall build a new TreeMap that is sorted by the Price
        // This is tricky, because it requires having **TWO** TreeMap's
        // **********************************************

        Comparator<String> comp = (String key1, String key2) -> 
            productsSortedByName.get(key1).compareTo(productsSortedByName.get(key2));

        // Build the TreeMap, and put the contents of the original TreeMap into the new one
        TreeMap<String, Double> productsSortedByPrice = new TreeMap<>(comp);
        productsSortedByPrice.putAll(productsSortedByName);
        
        // ********* Products are Sorted ****************
        // Now build the sorted JSON - this part is "self-explanatory."
        // AGAIN, this is how the JDK package "javax.json.*" can be used to create JSON
        // ********* Build Output Json ******************

        JsonArrayBuilder arrBuilder = Json.createArrayBuilder();
        
        for (String product : productsSortedByPrice.keySet())
            arrBuilder.add(Json.createObjectBuilder()
                .add("name", product)
                .add("cost", productsSortedByPrice.get(product).doubleValue()));
        
        String sortedJson = Json
            .createObjectBuilder()
            .add("products", arrBuilder)
            .add("details", obj.getJsonArray("details"))
            .build()
            .toString();
        
        // Print out the sorted JSON to terminal...
        System.out.println(sortedJson);
    }
}

The above code will print the following to terminal output:

{"products":[{"name":"Soap","cost":3.99},{"name":"Marble","cost":47.49},{"name":"Mixer","cost":59.99}],"details":[{"area":1090.098}]}
Sign up to request clarification or add additional context in comments.

Comments

0

If you don't want to create POJOs for your data model, you can use javax.json.json-api library to work directly with JSON.

See my maven file (after the code example) for the list of dependencies I added to my project.

package so;
import java.io.StringReader;
import java.io.StringWriter;

import javax.json.*;


public class SortExample {
    
    public JsonObject sortProductsByPrice(JsonObject order) {
        
        JsonArray products = order.getJsonArray("products");
        JsonArray details = order.getJsonArray("details");
        
        JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();

        
        products.stream().sorted((product1, product2) -> {
            JsonNumber cost1 = product1.asJsonObject().getJsonNumber("cost");
            JsonNumber cost2 = product2.asJsonObject().getJsonNumber("cost");
            return Double.compare(cost1.doubleValue(), cost2.doubleValue());
        }).forEach((value) -> arrayBuilder.add(value));
        
        
        JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
        
        objectBuilder.add("products", arrayBuilder.build());
        objectBuilder.add("details", details);
        
        return objectBuilder.build();
        
    }

    public static void main(String[] args) {
        
        String orderString = 
                "{\"products\": [ {\"Name\": \"Marble\",\"cost\": 47.49 }, { \"Name\": \"Mixer\",  \"cost\": 59.99  },  { \"Name\": \"Soap\", \"cost\": 3.99  } ], \"details\" : [ { \"area\" : 1090.098  } ] }";
        
                
        JsonObject order = Json.createReader(new StringReader(orderString)).readObject();
        
        JsonObject sortedOrder = new SortExample().sortProductsByPrice(order);
        
        StringWriter writer = new StringWriter();
        Json.createWriter(writer).writeObject(sortedOrder);
        
        System.out.println(writer.toString());
    }

}

Prints:

{"products":[{"Name":"Soap","cost":3.99},{"Name":"Marble","cost":47.49},{"Name":"Mixer","cost":59.99}],"details":[{"area":1090.098}]}

The main method in my example just constructs the payload from your example. The work is done in sortProductsByPrice.

It just leaves the products in their JsonValue representation and uses the streaming API to sort them and then place them back into a new JsonArray and finally builds up a new JsonObject with original details and sorted products.

I'm not familiar with javax.json and couldn't find a pretty print option. Perhaps a better library is available. But this gives you the gist of what you want to do.

Dependencies:

        <dependency>
            <groupId>javax.json</groupId>
            <artifactId>javax.json-api</artifactId>
            <version>1.1.4</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>1.1.4</version>
        </dependency>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.