Get latest jsons with respect to [version and name] key in subjson in java

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












This is the json



[

"SUBTASK":
"id": 10,
"name": "TestMap",
"description": "",
"version":"1.0"

,

"SUBTASK":
"id": 23,
"name": "TestMap",
"description": "",
"version":"2.0"

,

"SUBTASK":
"id": 12,
"name": "Tree",
"description": "",
"version":"13.0"

,

"SUBTASK":
"id": 32,
"name": "Tree",
"description": "",
"version":"10.0"


]


Need to get latest among the number of SUBTASKS ie. filter the latest versions of SUBTASK with respected to name.



So the final json will be like:



final:["SUBTASK":"id":12.0,"name":"Tree","description":"","version":"13.0","SUBTASK":"id":23.0,"name":"TestMap","description":"","version":"2.0"]


I achived using the below the java code :



Java Snippet



 public void getLatest(String json) throws Exception 
// converting json to java Object
List<Map<String, Object>> taskList = new Gson().fromJson(json, new TypeToken<List<Map<String, Object>>>()
.getType());

Map<String, Object> taskVersionedMap = new HashMap<String, Object>();

for (int i = 0; i < taskList.size(); i++)
Map<String, Object> processMap = taskList.get(i);
Map<String, Object> process = (Map<String, Object>) processMap.get("SUBTASK");

String process_name = process.get("name").toString() + "_" + process.get("version");
taskVersionedMap.put(process_name, processMap);

for (Map.Entry<String, Object> entry : taskVersionedMap.entrySet())
String split = entry.getKey().split("_");
double version = Double.parseDouble(split[1]);
String name = split[0];
for (Map.Entry<String, Object> entry2 : taskVersionedMap.entrySet())
String split_2 = entry2.getKey().split("_");
double version_2 = Double.parseDouble(split_2[1]);
String name_2 = split_2[0];
if (name.equals(name_2))
if (version < version_2)
String removedProcessName = name + "_" + version;
taskVersionedMap.put(removedProcessName, "ignored");






List<Map<String, Object>> filteredVersionList = new ArrayList<Map<String, Object>>();
for (Map.Entry<String, Object> mapValues : taskVersionedMap.entrySet())
if (!mapValues.getValue().toString().equals("ignored"))
try
filteredVersionList.add((Map<String, Object>) mapValues.getValue());
catch (Exception e)
e.printStackTrace();



System.out.println("final:"+new Gson().toJson(filteredVersionList));




The above code gives accurate result expected and is time consuming.



But is it possible to optimize the code since real data json at process will be verry big almost 500 more subtasks







share|improve this question

























    up vote
    0
    down vote

    favorite












    This is the json



    [

    "SUBTASK":
    "id": 10,
    "name": "TestMap",
    "description": "",
    "version":"1.0"

    ,

    "SUBTASK":
    "id": 23,
    "name": "TestMap",
    "description": "",
    "version":"2.0"

    ,

    "SUBTASK":
    "id": 12,
    "name": "Tree",
    "description": "",
    "version":"13.0"

    ,

    "SUBTASK":
    "id": 32,
    "name": "Tree",
    "description": "",
    "version":"10.0"


    ]


    Need to get latest among the number of SUBTASKS ie. filter the latest versions of SUBTASK with respected to name.



    So the final json will be like:



    final:["SUBTASK":"id":12.0,"name":"Tree","description":"","version":"13.0","SUBTASK":"id":23.0,"name":"TestMap","description":"","version":"2.0"]


    I achived using the below the java code :



    Java Snippet



     public void getLatest(String json) throws Exception 
    // converting json to java Object
    List<Map<String, Object>> taskList = new Gson().fromJson(json, new TypeToken<List<Map<String, Object>>>()
    .getType());

    Map<String, Object> taskVersionedMap = new HashMap<String, Object>();

    for (int i = 0; i < taskList.size(); i++)
    Map<String, Object> processMap = taskList.get(i);
    Map<String, Object> process = (Map<String, Object>) processMap.get("SUBTASK");

    String process_name = process.get("name").toString() + "_" + process.get("version");
    taskVersionedMap.put(process_name, processMap);

    for (Map.Entry<String, Object> entry : taskVersionedMap.entrySet())
    String split = entry.getKey().split("_");
    double version = Double.parseDouble(split[1]);
    String name = split[0];
    for (Map.Entry<String, Object> entry2 : taskVersionedMap.entrySet())
    String split_2 = entry2.getKey().split("_");
    double version_2 = Double.parseDouble(split_2[1]);
    String name_2 = split_2[0];
    if (name.equals(name_2))
    if (version < version_2)
    String removedProcessName = name + "_" + version;
    taskVersionedMap.put(removedProcessName, "ignored");






    List<Map<String, Object>> filteredVersionList = new ArrayList<Map<String, Object>>();
    for (Map.Entry<String, Object> mapValues : taskVersionedMap.entrySet())
    if (!mapValues.getValue().toString().equals("ignored"))
    try
    filteredVersionList.add((Map<String, Object>) mapValues.getValue());
    catch (Exception e)
    e.printStackTrace();



    System.out.println("final:"+new Gson().toJson(filteredVersionList));




    The above code gives accurate result expected and is time consuming.



    But is it possible to optimize the code since real data json at process will be verry big almost 500 more subtasks







    share|improve this question





















      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      This is the json



      [

      "SUBTASK":
      "id": 10,
      "name": "TestMap",
      "description": "",
      "version":"1.0"

      ,

      "SUBTASK":
      "id": 23,
      "name": "TestMap",
      "description": "",
      "version":"2.0"

      ,

      "SUBTASK":
      "id": 12,
      "name": "Tree",
      "description": "",
      "version":"13.0"

      ,

      "SUBTASK":
      "id": 32,
      "name": "Tree",
      "description": "",
      "version":"10.0"


      ]


      Need to get latest among the number of SUBTASKS ie. filter the latest versions of SUBTASK with respected to name.



      So the final json will be like:



      final:["SUBTASK":"id":12.0,"name":"Tree","description":"","version":"13.0","SUBTASK":"id":23.0,"name":"TestMap","description":"","version":"2.0"]


      I achived using the below the java code :



      Java Snippet



       public void getLatest(String json) throws Exception 
      // converting json to java Object
      List<Map<String, Object>> taskList = new Gson().fromJson(json, new TypeToken<List<Map<String, Object>>>()
      .getType());

      Map<String, Object> taskVersionedMap = new HashMap<String, Object>();

      for (int i = 0; i < taskList.size(); i++)
      Map<String, Object> processMap = taskList.get(i);
      Map<String, Object> process = (Map<String, Object>) processMap.get("SUBTASK");

      String process_name = process.get("name").toString() + "_" + process.get("version");
      taskVersionedMap.put(process_name, processMap);

      for (Map.Entry<String, Object> entry : taskVersionedMap.entrySet())
      String split = entry.getKey().split("_");
      double version = Double.parseDouble(split[1]);
      String name = split[0];
      for (Map.Entry<String, Object> entry2 : taskVersionedMap.entrySet())
      String split_2 = entry2.getKey().split("_");
      double version_2 = Double.parseDouble(split_2[1]);
      String name_2 = split_2[0];
      if (name.equals(name_2))
      if (version < version_2)
      String removedProcessName = name + "_" + version;
      taskVersionedMap.put(removedProcessName, "ignored");






      List<Map<String, Object>> filteredVersionList = new ArrayList<Map<String, Object>>();
      for (Map.Entry<String, Object> mapValues : taskVersionedMap.entrySet())
      if (!mapValues.getValue().toString().equals("ignored"))
      try
      filteredVersionList.add((Map<String, Object>) mapValues.getValue());
      catch (Exception e)
      e.printStackTrace();



      System.out.println("final:"+new Gson().toJson(filteredVersionList));




      The above code gives accurate result expected and is time consuming.



      But is it possible to optimize the code since real data json at process will be verry big almost 500 more subtasks







      share|improve this question











      This is the json



      [

      "SUBTASK":
      "id": 10,
      "name": "TestMap",
      "description": "",
      "version":"1.0"

      ,

      "SUBTASK":
      "id": 23,
      "name": "TestMap",
      "description": "",
      "version":"2.0"

      ,

      "SUBTASK":
      "id": 12,
      "name": "Tree",
      "description": "",
      "version":"13.0"

      ,

      "SUBTASK":
      "id": 32,
      "name": "Tree",
      "description": "",
      "version":"10.0"


      ]


      Need to get latest among the number of SUBTASKS ie. filter the latest versions of SUBTASK with respected to name.



      So the final json will be like:



      final:["SUBTASK":"id":12.0,"name":"Tree","description":"","version":"13.0","SUBTASK":"id":23.0,"name":"TestMap","description":"","version":"2.0"]


      I achived using the below the java code :



      Java Snippet



       public void getLatest(String json) throws Exception 
      // converting json to java Object
      List<Map<String, Object>> taskList = new Gson().fromJson(json, new TypeToken<List<Map<String, Object>>>()
      .getType());

      Map<String, Object> taskVersionedMap = new HashMap<String, Object>();

      for (int i = 0; i < taskList.size(); i++)
      Map<String, Object> processMap = taskList.get(i);
      Map<String, Object> process = (Map<String, Object>) processMap.get("SUBTASK");

      String process_name = process.get("name").toString() + "_" + process.get("version");
      taskVersionedMap.put(process_name, processMap);

      for (Map.Entry<String, Object> entry : taskVersionedMap.entrySet())
      String split = entry.getKey().split("_");
      double version = Double.parseDouble(split[1]);
      String name = split[0];
      for (Map.Entry<String, Object> entry2 : taskVersionedMap.entrySet())
      String split_2 = entry2.getKey().split("_");
      double version_2 = Double.parseDouble(split_2[1]);
      String name_2 = split_2[0];
      if (name.equals(name_2))
      if (version < version_2)
      String removedProcessName = name + "_" + version;
      taskVersionedMap.put(removedProcessName, "ignored");






      List<Map<String, Object>> filteredVersionList = new ArrayList<Map<String, Object>>();
      for (Map.Entry<String, Object> mapValues : taskVersionedMap.entrySet())
      if (!mapValues.getValue().toString().equals("ignored"))
      try
      filteredVersionList.add((Map<String, Object>) mapValues.getValue());
      catch (Exception e)
      e.printStackTrace();



      System.out.println("final:"+new Gson().toJson(filteredVersionList));




      The above code gives accurate result expected and is time consuming.



      But is it possible to optimize the code since real data json at process will be verry big almost 500 more subtasks









      share|improve this question










      share|improve this question




      share|improve this question









      asked Jun 5 at 10:13









      Kishan C S

      1032




      1032




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.



          Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.



          As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:



          Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
          ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));


          Then, first group by name:



          Map<String, List<Map<String, Object>>> byName = taskList.stream()
          .collect(Collectors.groupingBy(extractName));


          ... which gives you a list of each task type in the value lists.



          Now, we can disregard the grouping keys and extract the maximum per list:



          List<Map<String, Object>> result = byName.values().stream()
          .map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
          .map(Optional::get)
          .collect(Collectors.toList());


          Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get to retrieve the value.



          All is left is to encode the result list back to json, e.g.



          String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);


          Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>> and another outer wrapper method to do the decoding and encoding. Do one thing in a method.






          share|improve this answer





















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195875%2fget-latest-jsons-with-respect-to-version-and-name-key-in-subjson-in-java%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote



            accepted










            First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.



            Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.



            As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:



            Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
            ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));


            Then, first group by name:



            Map<String, List<Map<String, Object>>> byName = taskList.stream()
            .collect(Collectors.groupingBy(extractName));


            ... which gives you a list of each task type in the value lists.



            Now, we can disregard the grouping keys and extract the maximum per list:



            List<Map<String, Object>> result = byName.values().stream()
            .map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
            .map(Optional::get)
            .collect(Collectors.toList());


            Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get to retrieve the value.



            All is left is to encode the result list back to json, e.g.



            String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);


            Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>> and another outer wrapper method to do the decoding and encoding. Do one thing in a method.






            share|improve this answer

























              up vote
              2
              down vote



              accepted










              First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.



              Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.



              As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:



              Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
              ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));


              Then, first group by name:



              Map<String, List<Map<String, Object>>> byName = taskList.stream()
              .collect(Collectors.groupingBy(extractName));


              ... which gives you a list of each task type in the value lists.



              Now, we can disregard the grouping keys and extract the maximum per list:



              List<Map<String, Object>> result = byName.values().stream()
              .map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
              .map(Optional::get)
              .collect(Collectors.toList());


              Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get to retrieve the value.



              All is left is to encode the result list back to json, e.g.



              String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);


              Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>> and another outer wrapper method to do the decoding and encoding. Do one thing in a method.






              share|improve this answer























                up vote
                2
                down vote



                accepted







                up vote
                2
                down vote



                accepted






                First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.



                Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.



                As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:



                Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
                ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));


                Then, first group by name:



                Map<String, List<Map<String, Object>>> byName = taskList.stream()
                .collect(Collectors.groupingBy(extractName));


                ... which gives you a list of each task type in the value lists.



                Now, we can disregard the grouping keys and extract the maximum per list:



                List<Map<String, Object>> result = byName.values().stream()
                .map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
                .map(Optional::get)
                .collect(Collectors.toList());


                Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get to retrieve the value.



                All is left is to encode the result list back to json, e.g.



                String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);


                Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>> and another outer wrapper method to do the decoding and encoding. Do one thing in a method.






                share|improve this answer













                First of all, you have a grouping operation by process name, then you have the task of finding the maximum by version number per group.



                Thus, instead of using nested loops and somehow mashing it all together, simply perform those operations.



                As standard operations like grouping and finding a maximum are alreay presenet in the java stream api, all we need is a few helpers to extract the name and the version:



                Function<Map<String, Object>, String> extractName = m -> (String) ((Map<String, Object>) m.get("SUBTASK")).get("name");
                ToDoubleFunction<Map<String, Object>> extractVersion = m -> Double.parseDouble((String) ((Map<String, Object>) m.get("SUBTASK")).get("version"));


                Then, first group by name:



                Map<String, List<Map<String, Object>>> byName = taskList.stream()
                .collect(Collectors.groupingBy(extractName));


                ... which gives you a list of each task type in the value lists.



                Now, we can disregard the grouping keys and extract the maximum per list:



                List<Map<String, Object>> result = byName.values().stream()
                .map(l -> l.stream().max(Comparator.comparingDouble(extractVersion)))
                .map(Optional::get)
                .collect(Collectors.toList());


                Note: the stream.max returns an optional, which would be unset for an empty list. As we cannot generate empty lists here, it is save to simply map via Optional::get to retrieve the value.



                All is left is to encode the result list back to json, e.g.



                String jsonResult = new GsonBuilder().setPrettyPrinting().create().toJson(result);


                Note however, that you should better use a method which operates directly on the data structures, i.e. input and output are List<Map<String, Object>> and another outer wrapper method to do the decoding and encoding. Do one thing in a method.







                share|improve this answer













                share|improve this answer



                share|improve this answer











                answered Jun 5 at 10:41









                mtj

                2,675212




                2,675212






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195875%2fget-latest-jsons-with-respect-to-version-and-name-key-in-subjson-in-java%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation