How to create a non-static list from JSON parse in java?

Viewed 200

I'm still relatively new to Java and have hit a problem in the project I'm currently working on. I'm trying to get data from UN Comtrade via an HTTP request and then to parse this into an ArrayList.

I've managed to do that with the code below, but what I would then like to do is create an additional 'getList' method in this class so that I can call the list from other parts of the program.

However, I can't figure out how to do this as the parse method is static and so the list that it creates is unaccessible. Can anyone help me out with this?

My main class:

public class Main {

    public static void main(String[] args) {
    
        ReporterArea reporterArea = new ReporterArea();
        reporterArea.fetchReporterArea();
    
    }

The reporter area class:

import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpClient;
import java.net.URI;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONObject;

public class ReporterArea {
    
    public void fetchReporterArea(){
        
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://comtrade.un.org/api/get?max=500&type=C&freq=A&px=HS&ps=2016&r=all&p=0&rg=2&cc=TOTAL")).build();
        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpResponse::body)
                .thenApply(ReporterArea::parse)
                .join();
    }
    
    public static String parse(String dataset){
        
        JSONObject countries = new JSONObject(dataset);
        
        ArrayList<String> list = new ArrayList<String>();
        JSONArray array = countries.getJSONArray("dataset");
        
        for (int i = 0; i < array.length(); i++){
            String combined = array.getJSONObject(i).optString("rtTitle") + "; " + array.getJSONObject(i).optString("rtCode");
            list.add(combined);
         } 
        
        for (String i : list){
            System.out.println(i);
           
        } 
        
        return null;
    }
}
2 Answers

If you don't want to change the api logic you can just create a private List myList variable and after the for block that adds elements to the list in the static method, write

private static List<String> myList; //edit added static keyword after OP's comment

for (int i = 0; i < array.length(); i++){
     String combined = array.getJSONObject(i).optString("rtTitle") + "; " + array.getJSONObject(i).optString("rtCode");
     list.add(combined);
} 
myList = new ArrayList<>(list);

After that you can create a public getter method like this:

public List<String> getList(){
    if(myList !=null) {
       return myList;
    } else {
       return new ArrayList<>();
    }
}

you have to be careful and be sure that the getList() method is called after the parse

If you need to get the list of the parsed strings you should just return it from the parse method, and it can be static because it does not depend on any instance data as mentioned above.

Then you may also want to refactor fetchReporterArea to return CompletableFuture<List<String>> if you really need to retrieve the data asynchronously.

import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpClient;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.json.JSONArray;
import org.json.JSONObject;

public class ReporterArea {

    public CompletableFuture<List<String>> fetchReporterArea() {

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(
                        "https://comtrade.un.org/api/get?max=500&type=C&freq=A&px=HS&ps=2016&r=all&p=0&rg=2&cc=TOTAL"))
                .build();
        return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpResponse::body)
                .thenApply(ReporterArea::parse);
    }

    public static List<String> parse(String dataset) {

        JSONObject countries = new JSONObject(dataset);

        List<String> list = new ArrayList<String>();
        JSONArray array = countries.getJSONArray("dataset");

        for (int i = 0; i < array.length(); i++) {
            JSONObject row = array.getJSONObject(i);
            
            list.add(row.optString("rtTitle") + "; " + row.optString("rtCode"));
        }
        
        return list;
    }
}

Then method main should be updated as follows:

    public static void main(String[] args) throws InterruptedException, ExecutionException {
         ReporterArea reporterArea = new ReporterArea();
         CompletableFuture<List<String>> asyncResult = reporterArea.fetchReporterArea();
         
         asyncResult.get().forEach(System.out::println);
    }

Output (abbreviated)

Albania; 8
Algeria; 12
Andorra; 20
Angola; 24
...
Related