假设您有一个用户列表,实际上该列表来自数据库存储库.
User alice = new User(1, "alice", "9akDj18xA");
User bob = new User(2, "bob", "mLih41nZxx");
User carol = new User(3, "carol", "tFxn2Ad70");
List<User> users = List.of(alice, bob, carol);
每个用户都有一个ID、一个名称和一个可用于访问第三方服务的密钥.
class User {
int id;
String name;
String consentKey;
public User(int id, String name, String consentKey) {
this.id = id;
this.name = name;
this.consentKey = consentKey;
}
}
有时,第三方服务返回的数据--医疗记录--看起来是这样的.
class MedicalRecord {
int userId;
String information;
public MedicalRecord(int userId, String information) {
this.userId = userId;
this.information = information;
}
}
但在其他情况下,当键无效时,它会返回NULL,因此我们会将其过滤掉.
// Calls a third party service that returns data for some users only
List<MedicalRecord> medicalRecords =
users.stream()
.map(user -> Optional.ofNullable(fetchMedicalRecord(user)))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
该任务是生成将用户数据与医疗记录相结合的报告,但仅在医疗记录存在的情况下.以下是我为实现此目的而编写的代码.
return users.stream()
.filter(
user -> {
Optional<MedicalRecord> medicalRecord =
medicalRecords.stream()
.filter(record -> record.userId == user.id)
.findFirst();
return medicalRecord.isPresent();
})
.map(
user -> {
MedicalRecord medicalRecord =
medicalRecords.stream()
.filter(record -> record.userId == user.id)
.findFirst()
.get();
// Both user and medical record are needed here
return generateReport(user, medicalRecord);
})
.collect(Collectors.toList());
The problem-从列表中查找病历需要两次:一次是每filter
次,另一次是每map
次.您可以将筛选器缩短为使用类似anyMatch
的内容,但我并不是要减少这里的行数.我正在寻找的是一种方法,既传递医疗记录(如果存在)和用户一口气到generateReport(user, medicalRecord)
.从理论上讲,它可能是允许MAP接受两个值的东西,例如map((user, medicalRecord) -> generateReport(user, medicalRecord))
.
请注意,这是一个简化的示例,我只是为了说明一个问题而编造的,所以忽略过滤器/映射范围之外的小问题.
如果您想要一个完整的工作示例,下面是运行这一切所需的两个函数.
private static MedicalRecord fetchMedicalRecord(User user) {
if (!user.consentKey.equals("tFxn2Ad70")) {
String information = String.format("%s's medical record", user.name);
return new MedicalRecord(user.id, information);
} else {
return null;
}
}
private String generateReport(User user, MedicalRecord medicalRecord) {
return String.format("%s's report - %s", user.name, medicalRecord.information);
}