如何使用可选参数从HashMap检索值

时间:2018-08-24 18:57:43

标签: java dictionary java-8 hashmap java-stream

我正在学习Java 8流,并且正在尝试重构一种方法。

说我有一个学校班级和一个school map,该学校按ID存储所有学校对象。每个学校对象都包含一个student map,该public Student getStudent(Map<String, School> schoolMap, String studentId) { return schoolMap.values().stream() .map(School::getStudentIdToStudentMap) .filter(map -> map.containsKey(studentId)) .map(map -> map.get(studentId)) .findAny().get(); } 存储了一堆学生。

在这种情况下,学生ID在整个学校中都是唯一的。

我有一个功能,可以按所有学校的ID检索学生。

schoolId

现在,我想更改功能以将public Student getStudent(Map<String, School> schoolMap, String schoolId /* can be null */, String studentId) { // TODO: Something that I have tried return schoolMap.get(schoolId) .getStudentIdToStudentMap() .get(studentId); } 用作过滤器。

schoolId

是否可以将这两个功能组合在一起?如果// remove only "undefined" var test = [ "test.testA:(number:'1')undefined", "test.testA:(number:'1') and undefined", ]; console.log(test.map(function (a) { return a.replace(/\bundefined\b/, ''); })); // remove the whole line var test2 = [ "test.testA:(number:'1')undefined", "test.testA:(number:'1') and undefined", ]; console.log(test2.map(function (a) { return a.replace(/^.*?\bundefined\b.*$/, ''); }));为空,请从所有学校招收该学生。还是只是在特定学校中查找并找回学生?

3 个答案:

答案 0 :(得分:4)

我敢打赌,这就是您要寻找的东西

public Student getStudent(Map<String, School> schoolMap, String schoolId, String studentId)
{
    return Optional.ofNullable(schoolId)             // schoolId might be null
          .map(id -> Stream.of(schoolMap.get(id)))   // get Stream<School> by  else
          .orElse(schoolMap.values().stream())       // ... get Stream of all Schools
          .flatMap(i -> i.getStudentIdToStudentMap() // students from 1/all schools ...
                         .entrySet().stream())       // flat map to Stream<Entry<..,..>>
          .collect(Collectors.toMap(                 // collect all entries bu key/value
              Entry::getKey, Entry::getValue))       // ... Map<String,Student> 
          .getOrDefault(studentId, null);            // get Student by id or else null
}

您必须在唯一已知的学校或所有学校中进行搜索。这个想法是基于搜索过程的共同特征。无论您迭代一所或所有已知学校,任何学校的发现都将保持不变。

或者从List<Student>获得Optional

public Student getStudent(Map<String, School> schoolMap, String schoolId, String studentId)
{
    return Optional.ofNullable(schoolId)                          // schoolId might be null
           .map(i -> Collections.singletonList(schoolMap.get(i))) // add School into List
           .orElse(new ArrayList<>(schoolMap.values()))           // ... else all schools
           .stream()
           .map(i -> i.getStudentIdToStudentMap()       // get Map of students from 1/all
                      .get(studentId))                  // ... find by studentId
           .filter(Objects::nonNull)                    // get rid of nulls
           .findFirst().orElse(null);                   // get Student by id or else null
}

答案 1 :(得分:2)

这将是IMO最清晰的方法:

public Student getStudent(Map<String, School> schoolMap,
                          String schoolId /* can be null */,
                          String studentId){
    if(schoolId == null){
        return getStudent(schoolMap, studentId); // delegate to overload
    } else{
        return schoolMap.get(schoolId)
            .getStudentIdToStudentMap()
            .get(studentId);
    }
}

并非总是需要对流进行所有操作。因此,将两者分开。可以在所有带有流的地图上进行搜索,也可以只从您有ID的学校中选择学生。

答案 2 :(得分:0)

这应该有效:

   public Student getStudent(Map<String, School> schoolMap, 
                              String schoolId /* can be null */, 
                              String studentId) {

        return schoolMap.entries()
                .stream().filter(
               //Either there is no id so all schools match or you match on the one 
               //you want
             entry -> schoolId == null || entry.getKey().equals(schoolId))
            .map(map -> map.getValue().get(studentId))
                .findAny()
                .get()
    }