使用Java 8 Stream从Map中检索具有特定属性的值



我有一个属性为userId的类UserCourseEntity

@AllArgsConstructor
@Getter
@ToString
public static class UserCourseEntity {
private String userId;
}

我有一个以UserCourseEntity对象为值的映射。

public final Map<String, UserCourseEntity> userCourses;

方法getUserCoursesByUserID接收UserCourseEntityuserId属性作为参数。

我想检查userCourses映射中是否有userId的值以不区分大小写的方式(即使用equalsIgnoreCase()(与给定的id匹配。

如果有这样的值,我需要将它们存储到一个列表中,否则抛出一个异常。

我想知道是否可以使用流重新实现此代码?

public List<UserCourseEntity> getUserCoursesByUserID(String userId) {
List<UserCourseEntity> list = new ArrayList<>();
for (Map.Entry<String, UserCourseEntity> entry : userCourses.entrySet()) {
UserCourseEntity userCourseEntityValue = entry.getValue();
String key = entry.getKey();
boolean isExist = userCourseEntityValue.getUserId().equalsIgnoreCase(userId);

if (!isExist) {
continue;
} else {
if (userCourseEntityValue.getUserId().equalsIgnoreCase(userId)) {
list.add(userCourses.get(key));
}
}
}
if (list.isEmpty()) {
logger.error("No data found");
throw new SpecificException("No data found with the given details");
}
return list;
}

我们可以使用流来实现它。

为此,我们需要在映射条目上创建一个流。筛选具有与userId匹配的值的条目。它通过从每个条目中提取值来转换流,并将它们收集到列表中。

注意: 没有办法从流内部抛出异常,因此负责该异常的if语句保留在其位置。

这就是它的实现方式:

public List<UserCourseEntity> getUserCoursesByUserID(String userId) {
List<UserCourseEntity> courses = userCourses.entrySet().stream()
.filter(entry -> entry.getValue().getUserId().equalsIgnoreCase(userId))
.map(Map.Entry::getValue)
.collect(Collectors.toList()); // or .toList() for Java 16+

if (courses.isEmpty()) {
logger.error("No data found");
throw new SpecificException("No data found with the given details");
}

return courses;
}

旁注:类设计的角度来看,如果有一个用户对象负责存储和操作有关其课程的信息(检索和更改(,则会更干净。

您可以维护一个用户集合,例如将id用户关联的HashMap。这将允许以方便的方式访问课程列表

HashMap的条目进行迭代并不是使用它的最佳方式

最新更新