Я пытаюсь изменить ключи Map на основе условной логики и проблем. Я новичок в API потоков Java 8. Допустим, у меня есть такая карта:
Map<String, String> map = new HashMap<>();
map.put("PLACEHOLDER", "some_data1");
map.put("Google", "some_data2");
map.put("Facebook", "some_data3");
map.put("Microsoft", "some_data4");
Когда я хотел бы сделать, это найти ссылки на PLACEHOLDER и условно изменить этот ключ на что-то еще на основе логического условия. Я чувствую, что это должно быть что-нибудь, как показано ниже, но это, конечно, даже не компилируется.
boolean condition = foo();
map = map.entrySet().stream().filter(entry -> "PLACEHOLDER".equals(entry.getKey()))
.map(key -> {
if (condition) {
return "Apple";
} else {
return "Netflix";
}
}).collect(Collectors.toMap(e -> e.getKey(), Map.Entry::getValue));
Я нашел этот вопрос, который заставляет меня думать, что, возможно, я не могу сделать это с API потоков Java 8. Надеюсь, кто-то лучше меня знает, как это сделать. Ссылка на Ideone, если вы хотите поиграть с ним.
@YCF_L ключ, что делает вещи немного страннее.
Не могли бы вы отредактировать свой вопрос в этом случае - "... и условно изменить его значение на другое" - это то, что вызывало путаницу. Обычно это означает «изменить значение, связанное с этим ключом».
Сообщите нам, если вы решили свою проблему. Если да, пожалуйста, принимать самый полезный ответ или добавьте свой собственный ответ, объясняющий, как вы его решили.




Вы отфильтровали все элементы, которые неPLACEHOLDER. Вам нужно добавить эту логику фильтра к вашей операции map:
final Map<String, String> output = input.entrySet().stream()
.map(e -> {
if (!e.getKey().equals("PLACEHOLDER")) {
return e;
}
if (condition) {
return new AbstractMap.SimpleImmutableEntry<>("Apple", e.getValue());
}
return new AbstractMap.SimpleImmutableEntry<>("Netflix", e.getValue());
}).collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
Но поскольку у вас гарантированно будет только один экземпляр PLACEHOLDER в Map, вы можете просто сделать
String placeholderData = input.remove("PLACEHOLDER");
if (placeholderData != null) {
input.put(condition ? "Apple" : "Netflix", placeholderData);
}
Если вы действительно хотите сделать это с помощью Stream, вам просто нужно переместить условную логику на этап сбора, например:
boolean condition = true;
map.entrySet().stream().collect(Collectors.toMap(
entry -> mapKey(entry.getKey(), condition), Map.Entry::getValue
));
где:
private static String mapKey(String key, boolean condition) {
if (!"PLACEHOLDER".equals(key)) {
return key;
}
if (condition) {
return "Apple";
} else {
return "Netflix";
}
}
Однако вторая часть Борис паук ответ с использованием Map.remove и Map.put кажется лучшим вариантом.
Я думаю, что ваш подход к волшебству с функцией сопоставления клавиш лучше, чем мой подход, основанный на map.
Не могли бы вы уточнить, хотите ли вы изменить ключ или значение?