Reputation: 408
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.
Upvotes: 0
Views: 1156
Reputation: 297
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
Upvotes: 0
Reputation: 67297
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'}]}
Upvotes: 1
Reputation: 11
You're getting that error message because
label -> label.getName().equals("some_name") && label.getValue().equals("some_value")).findFirst()
returns an Optional 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.
Upvotes: 0