如何在流java8中通过键获取所有不同的值
我目前正在学习一些关于流的知识。 我有以下JSONArray,我希望能够检索所有不同的xvalue如何在流java8中通过键获取所有不同的值,java,json,java-8,java-stream,Java,Json,Java 8,Java Stream,我目前正在学习一些关于流的知识。 我有以下JSONArray,我希望能够检索所有不同的xvalue datasets: { ds1: { xvalues: [ "(empty)", "x1", "x2" ] }, ds2: { xvalues: [ "(empty)", "x1", "x2", "x3" ] }
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);
}
List xvalues=arrayToStream(数据集)
.map(JSONObject.class::cast)
.map(数据集->{
试一试{
返回dataset.getJSONArray(“xvalues”);
}捕获(JSONException ex){
}
返回;
})
.distinct()
.collect((Collectors.toList());
私有静态流arrayToStream(JSONArray数组){
返回StreamSupport.stream(array.spliterator(),false);
}
使用.map(数据集->数据集.getJSONArray(“xvalues”)
(为清晰起见,省略try catch
块)是一个列表本身,后续调用distinct
用于流
检查列表本身及其所有内容是否与其他列表相同,并保留不同的列表
您需要将结构平面映射到Stream
,然后使用distinct
获取唯一的项。但是,首先需要转换
List xvalues=arrayToStream(数据集)
.map(JSONObject.class::cast)
.map(数据集->数据集->{
请尝试{return dataset.getJSONArray(“xvalues”);}
catch(JSONException ex){}
返回;})
.map(jsonArray->toJsonArray(jsonArray))//将其转换为列表
.flatMap(List::stream)//到流
.distinct()
.collect(Collectors.toList());
我相信使用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());
在“.flatMap(List::stream)”,IDE也抱怨“不能在非静态中调用静态方法”,你能不能用try,catch提供一个答案,因为这也给我带来了一些困难。1)你不能仅仅删除一段好的代码,因为它看起来很难看(事实上,可能会抛出一个选中的异常,因此事情变得有点棘手)2)您缺少
map(Something::toString)
3)什么是toJsonArray
?4) Stream
看起来不对劲我意识到在平面映射之前我必须将JSONArray
转换为List
。@andreTobilko我删除try catch
的唯一原因是为了清晰起见。我知道它一定在里面。什么不太对劲?你能解释一下吗?(可能有一个示例输入和输出。)可能重复的
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());
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" +
"}}";