我正在学习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.*$/, '');
}));
为空,请从所有学校招收该学生。还是只是在特定学校中查找并找回学生?
答案 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()
}