我正在为注册界面创建一个非常简单的表单验证工具,但是在使用LinkedHashMap及其entrySet生成的流时,我遇到了一些意外的行为。
我将验证结果存储在LinkedHashMap中,并按以下语句排序:
我将验证结果存储在LinkedHashMap中,并按以下语句排序:
Map<ValidationResult.SignUpField, Boolean> fieldStatuses = new LinkedHashMap<>();
fieldStatuses.put(EMAIL, isValidEmail(emailAddress));
fieldStatuses.put(USERNAME, isValidUsername(username));
fieldStatuses.put(BIRTHDAY, isValidBirthday(birthday));
fieldStatuses.put(PASSWORD, isValidPassword(password));
fieldStatuses.put(CONFIRM_PASSWORD, password.equals(confirmedPassword));
List<ValidationEntry> invalidFields = aggregateInvalidFields(fieldStatuses);
一次迭代会使得上述所有字段无效,除了“确认密码”之外。通过简单的for循环遍历条目集并省略有效结果,无效结果按以下顺序出现:
- 电子邮件
- 用户名
- 生日
- 密码
然后我尝试利用Android上可用的Stream API子集(针对版本25,最小为19,因此缺少Collectors.toMap()
):
private static List<ValidationEntry> aggregateInvalidFields(Map<ValidationResult.SignUpField, Boolean> fields) {
List<ValidationEntry> invalidFields = new ArrayList<>();
fields.entrySet()
.stream()
.filter(entry -> !entry.getValue())
.forEachOrdered(entry -> {
ValidationResult.SignUpField field = entry.getKey();
invalidFields.add(new ValidationEntry(field, lookUpErrorCode(field)));
});
return invalidFields;
}
但是这段代码的输出结果却是:
- 生日
- 密码
- 用户名
- 邮箱
这里到底发生了什么,为什么流操作的结果不遵循 LinkedHashMap
的插入顺序?请注意,如果我将forEachOrdered
替换为forEach
,它仍然不是按插入顺序排序的。
fields
和fieldStatuses
是同一个映射吗? - Ole V.V.EnumMap
呢? - Ole V.V.