如何在Java中从JSON解析创建一个非静态列表?

huangapple go评论150阅读模式
英文:

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

问题

以下是翻译好的内容:

我对Java还比较新遇到了我目前正在处理的项目中的一个问题我正在尝试通过HTTP请求从联合国贸易数据数据库UN Comtrade获取数据然后将其解析到一个ArrayList中

我已经使用下面的代码做到了这一点但接下来我想在这个类中创建一个额外的'getList'方法以便我可以从程序的其他部分调用该列表

然而我无法弄清楚如何做到这一点因为解析方法是静态的所以它创建的列表是不可访问的有谁能帮帮我吗

我的主要类

public class Main {

    public static void main(String[] args) {

        ReporterArea reporterArea = new ReporterArea();
        reporterArea.fetchReporterArea();

    }
}

报告员地区类

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;
    }
}
英文:

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(&quot;https://comtrade.un.org/api/get?max=500&amp;type=C&amp;freq=A&amp;px=HS&amp;ps=2016&amp;r=all&amp;p=0&amp;rg=2&amp;cc=TOTAL&quot;)).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&lt;String&gt; list = new ArrayList&lt;String&gt;();
JSONArray array = countries.getJSONArray(&quot;dataset&quot;);
for (int i = 0; i &lt; array.length(); i++){
String combined = array.getJSONObject(i).optString(&quot;rtTitle&quot;) + &quot;; &quot; + array.getJSONObject(i).optString(&quot;rtCode&quot;);
list.add(combined);
} 
for (String i : list){
System.out.println(i);
} 
return null;
}
}

答案1

得分: 1

如果您不想更改 API 逻辑,只需创建一个私有的 List<String> myList 变量,并且在添加元素到列表的静态方法的循环块之后,编写以下代码:

private static List&lt;String&gt; myList; // 在 OP 的评论后添加了 static 关键字

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

之后,您可以创建一个公共的 getter 方法,如下所示:

public List&lt;String&gt; getList(){
    if(myList !=null) {
       return myList;
    } else {
       return new ArrayList&lt;&gt;();
    }
}

您必须小心,并确保在解析之后调用 getList() 方法。

英文:

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

private static List&lt;String&gt; myList; //edit added static keyword after OP&#39;s comment
for (int i = 0; i &lt; array.length(); i++){
String combined = array.getJSONObject(i).optString(&quot;rtTitle&quot;) + &quot;; &quot; + array.getJSONObject(i).optString(&quot;rtCode&quot;);
list.add(combined);
} 
myList = new ArrayList&lt;&gt;(list);

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

public List&lt;String&gt; getList(){
if(myList !=null) {
return myList;
} else {
return new ArrayList&lt;&gt;();
}
}

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

答案2

得分: 0

如果您需要获取解析后的字符串列表,只需从parse方法中返回该列表即可。此方法可以是静态的,因为它不依赖于任何实例数据,正如上面提到的那样。

然后,如果您确实需要异步检索数据,您可能还希望重构fetchReporterArea方法以返回CompletableFuture&lt;List&lt;String&gt;&gt;类型。

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&lt;List&lt;String&gt;&gt; fetchReporterArea() {

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

    public static List&lt;String&gt; parse(String dataset) {

        JSONObject countries = new JSONObject(dataset);

        List&lt;String&gt; list = new ArrayList&lt;String&gt;();
        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;
    }
}

然后,main方法应更新如下:

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ReporterArea reporterArea = new ReporterArea();
        CompletableFuture&lt;List&lt;String&gt;&gt; asyncResult = reporterArea.fetchReporterArea();

        asyncResult.get().forEach(System.out::println);
    }

输出(缩写)

阿尔巴尼亚; 8
阿尔及利亚; 12
安道尔; 20
安哥拉; 24
...
英文:

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&lt;List&lt;String&gt;&gt; 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&lt;List&lt;String&gt;&gt; fetchReporterArea() {

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

	public static List&lt;String&gt; parse(String dataset) {

		JSONObject countries = new JSONObject(dataset);

		List&lt;String&gt; list = new ArrayList&lt;String&gt;();
		JSONArray array = countries.getJSONArray(&quot;dataset&quot;);

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

Then method main should be updated as follows:

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

Output (abbreviated)

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

huangapple
  • 本文由 发表于 2020年8月31日 19:00:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63669551.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定