I’m having simple DataStructure
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:
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 :
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
.