【发布时间】:2017-03-10 06:07:21
【问题描述】:
我正在为注册屏幕创建一个非常简单的表单验证实用程序,但我遇到了一些关于 LinkedHashMap 和从其 entrySet 创建的流的意外行为。
我将验证结果存储在 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,它仍然不是插入顺序。
【问题讨论】:
-
你能显示你的插入代码吗?
-
确定,现在更新
-
什么是
invalidFields? -
那你为什么不使用
EnumMap? -
你能试着把它减少到minimal reproducible example吗?很难知道你是否遗漏了一些重要的东西。
标签: java android java-stream linkedhashmap