Java流按键查找值(如果存在)

Java流按键查找值(如果存在),java,java-stream,Java,Java Stream,我有简单的数据结构 public class DataStructure { private String key; private String value; //get, set } 我需要根据键从'List'返回值,我想用Java8的方式,用streams。我认为代码说明了一切: public class Main { public static void main(String args[]) { List<DataStructure&

我有简单的数据结构

public class DataStructure {
    private String key;
    private String value;
    //get, set
}
我需要根据键从'List'返回值,我想用Java8的方式,用streams。我认为代码说明了一切:

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();
    }
}
公共类主{
公共静态void main(字符串参数[]){
List dataList=new ArrayList();
添加(新的数据结构(“第一”、“123”);
添加(新的数据结构(“第二”、“456”);
System.out.println(findValueOldSchool(数据列表,“第三”);//工作正常
System.out.println(findValueStream(dataList,“third”);//抛出NoSuchElementException
}
静态字符串findValueOldSchool(列表,字符串键){
对于(数据结构ds:list){
if(key.equals(ds.getKey())){
返回ds.getValue();
}
}
返回null;
}
静态字符串findValueStream(列表、字符串键){
return list.stream()
.filter(ds->key.equals(ds.getKey()))
.findFirst()
.get().getValue();
}
}

如何修改
findValueStream()
以在搜索不存在的键时不抛出NoSuchValueException?我不想返回
Optional
,因为这个方法已经在project的很多地方使用过了。当然,我试过
map
ifPresent
anyMatch
,就是找不到正确的方法

如果可选项的状态为空,则使用
orElse
返回默认值:

这也意味着您需要首先映射到
DataStructure::getValue
,如下所示:

return list.stream()
           .filter(ds -> key.equals(ds.getKey()))
           .findFirst()
           .map(DataStructure::getValue)
           .orElse(null);
仅将
get
替换为
orElse
不够:

 return list.stream()
            .filter(ds -> key.equals(ds.getKey()))
            .findFirst()
            .orElse(null)
            .getValue();
因为这一次,如果是空的可选项,您将得到一个
NullPointerException
,而不是
NoTouchElementException

您应该与类似的选项一起使用:

静态字符串findValueStream(列表,字符串键){
return list.stream()//初始流
.filter(ds->key.equals(ds.getKey())//过滤流
.map(DataStructure::getValue)//映射流
.findFirst()//第一个可选
.orElse(null);//否则返回'null'
}

注意:上面使用将
数据结构流
映射到相应的
值流

.findFirst().orElse(null)
如果返回一个可为null的函数,则将失去可选的好处。我会选择返回类型也必须是
map
ping到
getValue
是的,我是指没有流实现的OP共享的代码中的getValue。@shmosel同意,我的意思是,这里提出的当前解决方案必须确保映射已经完成。@nullpointer Right,使答案更准确“明确”,有时当我发布答案时,我只是假设缺少的部分(如果有的话)是不言自明的。
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'
}