英文:
Filter attribute from a list of object nested in another list of object using stream
问题
对于以下的类结构,从 List<SomeClass>
中,对于给定的 name
和 fieldName
,我想要得到一组 fieldValue
值的列表。可能会有多个 name
的出现。
class SomeClass {
String name;
List<SomeField> fields;
}
class SomeField {
String fieldName;
String fieldValue;
}
这是我迄今为止在没有使用流(stream)的情况下所做的 -
for (SomeClass aClass : classes) {
if (aClass.getName().equalsIgnoreCase(givenName)) {
for (SomeField aField : aClass.getSomeField()) {
if (aField.getFieldName().equalsIgnoreCase(givenFieldName)) {
outputList.add(aField.getFieldValue());
}
}
}
}
我尝试将此转换为流(stream),但我只达到了这里。我无法弄清楚如何进行下一步(从这一点开始获取 SomeField
列表并根据 fieldName
进行过滤) -
classes.stream()
.filter(e -> e.getName().equalsIgnoreCase(givenName))
.collect(Collectors.toList());
希望能得到帮助。
示例输入:
[
{
"name": "a",
"fields": [
{
"fieldName": "n1",
"fieldValue": "v1"
},
{
"fieldName": "n2",
"fieldValue": "v2"
}
]
},
{
"name": "a",
"fields": [
{
"fieldName": "n1",
"fieldValue": "v3"
}
]
},
{
"name": "b",
"fields": [
{
"fieldName": "n1",
"fieldValue": "v4"
}
]
}
]
对于 givenName = "a"
和 givenFieldName = "n1"
:
期望的输出:["v1", "v3"]
英文:
For the following class structure, from a List<SomeClass>
, for a given name
and fieldName
, I want to get a list of fieldValue
s. There can be multiple occurrences of name
class SomeClass {
String name;
List<SomeField> fields;
}
class SomeField {
String fieldName;
String fieldValue;
}
This is what I have done so far without stream -
for (SomeClass aClass : classes) {
if (aClass.getName().equalsIgnoreCase(givenName)) {
for (SomeField aField : aClass.getSomeField()) {
if (aField.getFieldName().equalsIgnoreCase(givenFieldName)) {
outputList.add(aField.getFieldValue());
}
}
}
}
I have tried to convert this to stream, but I only reached till here. I could not figure out how to proceed to the next step (getting list of SomeField
from this point and filtering based on fieldName
) -
classes.stream()
.filter(e -> e.getName().equalsIgnoreCase(givenName))
.collect(Collectors.toList());
Any help would be appreciated.
Sample input:
[
{
"name":"a",
"fields":[
{
"fieldName":"n1",
"fieldValue":"v1"
},
{
"fieldName":"n2",
"fieldValue":"v2"
}
]
},
{
"name":"a",
"fields":[
{
"fieldName":"n1",
"fieldValue":"v3"
}
]
},
{
"name":"b",
"fields":[
{
"fieldName":"n1",
"fieldValue":"v4"
}
]
}
]
for givenName = "a"
and givenFieldName = "n1"
:
expected output : ["v1","v3"]
答案1
得分: 2
使用map()
和flatMap()
。
public class Main {
public static void main(String[] args) {
String givenName = "a";
String givenFieldName = "n1";
List<SomeClass> classes = new ArrayList<>();
classes.add(new SomeClass("a", List.of(new SomeField("n1", "v1"), new SomeField("n2", "v2"))));
classes.add(new SomeClass("a", List.of(new SomeField("n1", "v3"))));
classes.add(new SomeClass("b", List.of(new SomeField("n1", "v4"))));
List<String> result = classes
.stream()
.filter(c -> c.name.equalsIgnoreCase(givenName))
.flatMap(c -> c.fields.stream())
.filter(f -> f.fieldName.equalsIgnoreCase(givenFieldName))
.map(f -> f.fieldValue)
.collect(Collectors.toList());
System.out.println(result);
}
}
class SomeClass {
String name;
List<SomeField> fields;
public SomeClass(String name, List<SomeField> fields) {
this.name = name;
this.fields = fields;
}
}
class SomeField {
String fieldName;
String fieldValue;
public SomeField(String fieldName, String fieldValue) {
this.fieldName = fieldName;
this.fieldValue = fieldValue;
}
}
英文:
Use map()
and flatMap()
.
public class Main {
public static void main(String[] args) {
String givenName = "a";
String givenFieldName = "n1";
List<SomeClass> classes = new ArrayList<>();
classes.add(new SomeClass("a", List.of(new SomeField("n1", "v1"), new SomeField("n2", "v2"))));
classes.add(new SomeClass("a", List.of(new SomeField("n1", "v3"))));
classes.add(new SomeClass("b", List.of(new SomeField("n1", "v4"))));
List<String> result = classes
.stream()
.filter(c -> c.name.equalsIgnoreCase(givenName))
.flatMap(c -> c.fields.stream())
.filter(f -> f.fieldName.equalsIgnoreCase(givenFieldName))
.map(f -> f.fieldValue)
.collect(Collectors.toList());
System.out.println(result);
}
}
class SomeClass {
String name;
List<SomeField> fields;
public SomeClass(String name, List<SomeField> fields) {
this.name = name;
this.fields = fields;
}
}
class SomeField {
String fieldName;
String fieldValue;
public SomeField(String fieldName, String fieldValue) {
this.fieldName = fieldName;
this.fieldValue = fieldValue;
}
}
答案2
得分: 1
使用flatMap
对List<SomeField>
进行扁平化,然后根据条件进行过滤,然后仅映射fieldValue
并获取fieldValue
的列表。
List<String> res = classes.stream()
.filter(e -> e.getName().equalsIgnoreCase(givenName))
.flatMap(m -> m.getSomeField().stream())
.filter(f -> f.getFieldName().equalsIgnoreCase(givenFieldName))
.map(e -> e.getFieldValue())
.collect(Collectors.toList());
英文:
Use flatMap
to flat the List<SomeField>
then filter by condition then map only fieldValue
and get the list of fieldValue
.
List<String> res = classes.stream()
.filter(e -> e.getName().equalsIgnoreCase(givenName))
.flatMap(m -> m.getSomeField().stream())
.filter(f -> f.getFieldName().equalsIgnoreCase(givenFieldName))
.map(e -> e.getFieldValue())
.collect(Collectors.toList());
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论