Этого можно добиться с помощью простой логики рекурсии в вспомогательной функции:
public static String findCorrespondingValue(Map<String, String> map, String key){
if(map.containsKey(key)){
return findCorrespondingValue(map, map.get(key));
}
return key;
}
Как говорилось, логика очень проста, мы просто проверяем, существует ли для данного key
значение в данном map
- если да, то мы снова выполняем функцию, но на этот раз с
value
в качестве
новый key
.
- если сопоставления не существует, мы можем с уверенностью сказать, что данный
key
является последним
значение в цепочке
Вы можете вызвать метод следующим образом:
Map<String, String> testMap = ... // setup testMap
Map<String, String> result = new HashMap<>();
for (final Entry<String, String> entry : testMap.entrySet()) {
result.put(
entry.getKey(),
findCorrespondingValue(testMap, entry.getValue())
);
}
или если вы использовали java 8:
Map<String, String> result = testMap.entrySet().stream()
.collect(Collectors.toMap(
e -> e.getKey(), // or just Map.Entry::getKey
e -> findCorrespondingValue(e.getValue())
));
Вам, конечно, придется реализовать какую-то логику, чтобы выяснить, есть ли у вас циклические ссылки. Например:
a -> b
b -> f
f -> a
Который сейчас просто потерпит неудачу с StackOverflowError
.
Вы можете сделать это также общим, если вы хотите поддерживать несколько различных типов, а не только String
:
public static <T> T findCorrespondingValue(Map<? extends T, ? extends T> map, T key){
if(map.containsKey(key)){
return findCorrespondingValue(map, map.get(key));
}
return key;
}