英文:
Java 8 find element matching in a list of objects where each object has another object
问题
I have two classes:
class SampleClass {
private String testString;
private List
class Label {
private String labelName;
private String labelValue;
}
I have a `List<SampleClass> sampleClassList`. I need to find the find element in the list which has a particular `labelName` and `labelValue` using Java 8.
If I need to get the `SampleClass` object based on `testString` I would do,
Optional
Now that the filtering involves `Label` class, I am unable to figure out how to do that. I have tried something like,
Optional
entry.getLabels().stream().anyMatch(label ->
label.getLabelName().equals("some_name") &&
label.getLabelValue().equals("some_value"))).findFirst();
for which I get `Bad return type in lambda expression: Optional<Label> cannot be converted to boolean`. How would I go about making this change?
I could make it work by using `contains()` method
final Optional
.filter(entry -> entry.getLabels()
.contains(new Label().withLabelName("some_name").withLabelValue("some_value")))
.findFirst();
but would like to know if I can still use `stream()` to make this happen.
英文:
I have two classes:
class SampleClass {
private String testString;
private List<Label> labels;
}
class Label {
private String labelName;
private String labelValue;
}
I have a List<SampleClass> sampleClassList
. I need to find the find element in the list which has a particular labelName
and labelValue
using Java 8.
If I need to get the SampleClass
object based on testString
I would do,
Optional<SampleClass> sampleClass = sampleClassList.stream().filter(entry -> entry.getTestString().equals("some_value").findFirst();
Now that the filtering involves Label
class, I am unable to figure out how to do that. I have tried something like,
Optional<SampleClass> sampleClass = sampleClassList.stream().filter(entry ->
entry.getLabels().stream().filter(label ->
label.getName().equals("some_name") &&
label.getValue().equals("some_value")).findFirst()).findFirst();
for which I get Bad return type in lambda expression: Optional<Label> cannot be converted to boolean
. How would I go about making this change?
I could make it work by using contains()
method
final Optional<SampleClass> sampleClass = sampleClassList.stream()
.filter(entry -> entry.getLabels()
.contains(new Label().withLabelName("some_name").withLabelValue("some_value")))
.findFirst();
but would like to know if I can still use stream()
to make this happen.
答案1
得分: 1
如何看待这个问题?不使用建议的 `findFirst().isPresent()`,你可以直接使用 `anyMatch()`
public class Label {
private String name;
private String value;
public Label(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return "Label{" + "name='" + name + '\'' + ", value='" + value + '\'' + '}';
}
}
class SampleClass {
private String testString;
private List<Label> labels;
public SampleClass(String testString, List<Label> labels) {
this.testString = testString;
this.labels = labels;
}
public List<Label> getLabels() {
return labels;
}
@Override
public String toString() {
return "SampleClass{" + "testString='" + testString + '\'' + ", labels=" + labels + '}';
}
}
import java.util.List;
import java.util.Optional;
class Scratch {
public static void main(String[] args) {
List<SampleClass> sampleClassList = List.of(
new SampleClass("111", List.of(new Label("one", "one value"), new Label("two", "two value"))),
new SampleClass("222", List.of(new Label("one", "one value"), new Label("two", "two value"))),
new SampleClass("333", List.of(new Label("some_name", "some_value"), new Label("two", "two value")))
);
Optional<SampleClass> sampleClass = sampleClassList.stream()
.filter(entry ->
entry.getLabels().stream()
.anyMatch(label ->
label.getName().equals("some_name") &&
label.getValue().equals("some_value")
)
)
.findFirst();
System.out.println(sampleClass.orElse(null));
}
}
这将打印出:
SampleClass{testString='333', labels=[Label{name='some_name', value='some_value'}, Label{name='two', value='two value'}]}
英文:
How about this? Instead of the suggested findFirst().isPresent()
you can just use anyMatch()
public class Label {
private String name;
private String value;
public Label(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return "Label{" + "name='" + name + '\'' + ", value='" + value + '\'' + '}';
}
}
class SampleClass {
private String testString;
private List<Label> labels;
public SampleClass(String testString, List<Label> labels) {
this.testString = testString;
this.labels = labels;
}
public List<Label> getLabels() {
return labels;
}
@Override
public String toString() {
return "SampleClass{" + "testString='" + testString + '\'' + ", labels=" + labels + '}';
}
}
import java.util.List;
import java.util.Optional;
class Scratch {
public static void main(String[] args) {
List<SampleClass> sampleClassList = List.of(
new SampleClass("111", List.of(new Label("one", "one value"), new Label("two", "two value"))),
new SampleClass("222", List.of(new Label("one", "one value"), new Label("two", "two value"))),
new SampleClass("333", List.of(new Label("some_name", "some_value"), new Label("two", "two value")))
);
Optional<SampleClass> sampleClass = sampleClassList.stream()
.filter(entry ->
entry.getLabels().stream()
.anyMatch(label ->
label.getName().equals("some_name") &&
label.getValue().equals("some_value")
)
)
.findFirst();
System.out.println(sampleClass.orElse(null));
}
}
This should print:
SampleClass{testString='333', labels=[Label{name='some_name', value='some_value'}, Label{name='two', value='two value'}]}
答案2
得分: 0
你之所以收到该错误信息,是因为
label -> label.getName().equals("some_name") && label.getValue().equals("some_value")).findFirst()
返回一个Optional
英文:
You're getting that error message because
label -> label.getName().equals("some_name") && label.getValue().equals("some_value")).findFirst()
returns an Optional<Label> when Java needs a boolean for your outer filter. Essentially you're saying give me an Optional that contains the value if it exists. If you change the findFirst() to isPresent() then that will give you the boolean you need as isPresent() just says return true if the value exists.
答案3
得分: 0
sampleClassList.stream().filter(entry ->
entry.getLabels().stream().filter(label ->
label.getName().equals("some_name") &&
label.getValue().equals("some_value")).count() > 0).findFirst();
在过滤内部标签列表后使用 count() > 0。
英文:
sampleClassList.stream().filter(entry ->
entry.getLabels().stream().filter(label ->
label.getName().equals("some_name") &&
label.getValue().equals("some_value")).count() > 0).findFirst();
use count() > 0 after filtering on inner labels List
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论