如何通过流java8中的键获取所有不同的值

问题描述 投票:3回答:2

我目前正在学习一些有关流的知识。我具有以下JSONArray,并且我希望能够检索所有不同的xvalue。

 datasets: {
    ds1: {
     xvalues: [
        "(empty)",
        "x1",
        "x2"
      ]
    },
    ds2: {
    xvalues: [
        "(empty)",
        "x1",
        "x2",
        "x3"
      ]
    }
}

我正在尝试以下代码,但似乎不太正确。...

List<String> xvalues = arrayToStream(datasets)
                .map(JSONObject.class::cast)
                .map(dataset -> {
                    try {
                         return dataset.getJSONArray("xvalues");
                    } catch (JSONException ex) {

                    }
                    return;
            })
            .distinct()
            .collect((Collectors.toList()));

private static Stream<Object> arrayToStream(JSONArray array) {
    return StreamSupport.stream(array.spliterator(), false);
}
java json java-8 java-stream
2个回答
1
投票

我相信使用json库(Jackson,Gson)是处理json数据的最佳方法。如果可以使用Jackson,这可能是一个解决方案

public class DataSetsWrapper {   
    private Map<String, XValue> datasets;
    //Getters, Setters
}

public class XValue {
    private List<String> xvalues;
    //Getters, Setters
}  



ObjectMapper objectMapper = new ObjectMapper();
DataSetsWrapper dataSetsWrapper = objectMapper.readValue(jsonString, DataSetsWrapper.class);

List<String> distinctXValues = dataSetsWrapper.getDatasets()
                .values()
                .stream()
                .map(XValue::getXvalues)
                .flatMap(Collection::stream)
                .distinct()
                .collect(Collectors.toList()); 

用您的json替换jsonString。我用这个json测试了这个

String jsonString = "{\"datasets\": {\n" +
        "    \"ds1\": {\n" +
        "     \"xvalues\": [\n" +
        "        \"(empty)\",\n" +
        "        \"x1\",\n" +
        "        \"x2\"\n" +
        "      ]\n" +
        "    },\n" +
        "    \"ds2\": {\n" +
        "    \"xvalues\": [\n" +
        "        \"(empty)\",\n" +
        "        \"x1\",\n" +
        "        \"x2\",\n" +
        "        \"x3\"\n" +
        "      ]\n" +
        "    }\n" +
        "}}";

0
投票

.map(dataset -> dataset.getJSONArray("xvalues")的结果(为清楚起见,省略了try-catch块)是列表本身,随后在distinct上使用了Stream<List<Object>>的调用,以检查列表本身及其所有内容是否相同到另一个并留下不同的列表。

您需要将结构平面映射到Stream<Object>,然后使用distinct获取唯一项。但是,首先,您需要转换JSONArray to List

List<String> xvalues = arrayToStream(datasets)
    .map(JSONObject.class::cast)
    .map(dataset -> dataset -> {
         try { return dataset.getJSONArray("xvalues"); } 
         catch (JSONException ex) {}
         return;})
    .map(jsonArray -> toJsonArray(jsonArray ))         // convert it to List
    .flatMap(List::stream)                             // to Stream<Object>
    .distinct()
    .collect(Collectors.toList());
© www.soinside.com 2019 - 2024. All rights reserved.