I’m having simple DataStructure
JavaScript
x
public class DataStructure {
private String key;
private String value;
//get, set
}
And I need to return value from `List’ based on key and I want to do it Java8 way, with streams. I think code speaks for himself:
JavaScript
public class Main {
public static void main(String args[]) {
List<DataStructure> dataList = new ArrayList<>();
dataList.add(new DataStructure("first", "123"));
dataList.add(new DataStructure("second", "456"));
System.out.println(findValueOldSchool(dataList, "third")); //works ok
System.out.println(findValueStream(dataList, "third")); //throws NoSuchElementException
}
static String findValueOldSchool(List<DataStructure> list, String key) {
for (DataStructure ds : list) {
if (key.equals(ds.getKey())) {
return ds.getValue();
}
}
return null;
}
static String findValueStream(List<DataStructure> list, String key) {
return list.stream()
.filter(ds -> key.equals(ds.getKey()))
.findFirst()
.get().getValue();
}
}
How can I modify findValueStream()
to not throw NoSuchValueException while I search for non existing key? I don’t want to return Optional<String>
because this method is already used in a lot of places in project. And, ofcourse I’v tried map
, ifPresent
, anyMatch
, just can’t find the right way to do it.
Advertisement
Answer
You shall use Stream.findFirst
with an Optional.orElse
like :
JavaScript
static String findValueStream(List<DataStructure> list, String key) {
return list.stream() // initial Stream<DataStructure>
.filter(ds -> key.equals(ds.getKey())) // filtered Stream<DataStructure>
.map(DataStructure::getValue) // mapped Stream<String>
.findFirst() // first Optional<String>
.orElse(null); // or else return 'null'
}
Note: The above uses the Stream.map
to map the stream of DataStructure
to a corresponding stream of value
.