Как получить значение из HashMap с необязательным аргументом - PullRequest
0 голосов
/ 24 августа 2018

Я изучаю потоки Java 8 и пытаюсь реорганизовать метод.

Допустим, у меня есть класс School и 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();
}

СейчасЯ хочу изменить функцию на использование 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 пусто, отведите ученика из всех школ.Еще просто поискать в конкретной школе и забрать ученика?

Ответы [ 3 ]

0 голосов
/ 25 августа 2018

Это был бы самый ясный способ ИМО:

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);
    }
}

Не всегда нужно делать все с потоками.Так что разделите два на частиЛибо ищите по всем картам с потоками, либо просто выберите ученика из школы, откуда у вас есть идентификатор.

0 голосов
/ 25 августа 2018

Бьюсь об заклад, это то, что вы ищете:

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
}
0 голосов
/ 25 августа 2018

Это должно работать:

   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()
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...