#java #dictionary #hashmap #iteration
#java #словарь #hashmap #итерация
Вопрос:
У меня есть Map<String>,Set<String>> followingMap
, где ключи — это имена пользователей, а значения — это наборы имен пользователей, за которыми следуют ключевые имена пользователей. Я должен создать followersMap , где в этом случае подписанные пользователи в наборах значений теперь являются ключами, а значение представляет собой набор подписчиков в соответствии с предыдущим k.
Не уверен, что это достаточно понятно, поэтому в качестве примера элемент в следующей карте будет: key="john", value=Set["robert","andrew,"amanda"].
В followersMap это было бы:
key="robert", value=Set["john"]
key="andrew", value=Set["john"]
key="amanda", value=Set["john"]
Если вторым элементом в followingMap является key="alex",Set["amanda"]
, это добавило бы «alex» к набору значений ключа «amanda».
Мой код должен выполнить трюк, однако при тестировании я получаю ключи, в которых заполняются все установленные значения.
Взгляните:
Map<String,Set<String>> followerGraph = new HashMap<String,Set<String>>();
for (Map.Entry<String, Set<String>> me : followsGraph.entrySet()) {
String key = me.getKey();
Set<String> tmp = new LinkedHashSet<>();
Set<String> valueSet = me.getValue();
for (String s : valueSet) {
if (followerGraph.containsKey(s)){
followerGraph.get(s).add(key);
} else {
tmp.add(key);
followerGraph.put(s, tmp);
}
}
}
Итак, это печать следующего графика:
{aliana=[@jake, @john, @erick], alyssa=[@john, @erick],
bbitdiddle=[@rock-smith, @john, @erick], casus=[@daniel, @jake, @john, @erick],
david=[@dude, @john]}
И это печать следующего графика:
{@daniel=[casus], @rock-smith=[bbitdiddle], @jake=[aliana, alyssa, bbitdiddle, casus, david], @dude=[david], @john=[aliana, alyssa, bbitdiddle, casus, david], @erick=[aliana, alyssa, bbitdiddle, casus, david]}
Как вы можете видеть, у @erick не должно быть подписчика Дэвида. Я что-то упускаю?
Извините, если мой код выглядит как беспорядок. Я всего 6 месяцев в Java, 4 часа изучаю, как повторять карту (пробовал потоки Java 8, но не уверен, как добавить туда if-else), и сейчас 6 утра, и моя жена может убить меня за то, что я не спал всю ночь : S
Комментарии:
1. Откуда берется следующий график?
2. Вы правы. Я не включил эту строку. Это вторая карта <String,Set<String>>, которая отображает последователей
Ответ №1:
Вы можете сделать что-то подобное:
Map<String, Set<String>> followerMap = new HashMap<>();
followingMap.forEach((name,followingSet)-> followingSet.forEach(
follower-> followerMap.computeIfAbsent(follower, f->new HashSet<>())
.add(name)));
followingMap.forEach
обработайте все записи в следующей карте. Затем набор каждой записи обрабатывается с помощью followingSet.forEach
. Элементами этого набора являются последователи, ключи новой карты. computeIfAbsent
используется для размещения новой записи на карте, если она не существует, добавляя пустой набор в этом случае. После этого значение добавляется к набору, в данном случае к записи следующей карты.
И это тот же код, использующий for
циклы вместо forEach
, вероятно, более читаемый.
Map<String, Set<String>> followerMap = new HashMap<>();
for (Entry<String, Set<String>> followingEntry : followingMap.entrySet()) {
for (String follower : followingEntry.getValue()) {
followerMap.computeIfAbsent(follower, s->new HashSet<>()).add(followingEntry.getKey());
}
}
Комментарии:
1. @WesleyDeKeirsmaeker Вы, вероятно, правы, вероятно, использование
for
циклов вместоforEach
методов делает ее более читаемой
Ответ №2:
Попробуйте это.
for (Map.Entry<String, Set<String>> me : followsGraph.entrySet()) {
String key = me.getKey();
// Set<String> tmp = new LinkedHashSet<>(); // MOVE THIS TO ...
Set<String> valueSet = me.getValue();
for (String s : valueSet) {
if (followerGraph.containsKey(s)) {
followerGraph.get(s).add(key);
} else {
Set<String> tmp = new LinkedHashSet<>(); // HERE
tmp.add(key);
followerGraph.put(s, tmp);
}
}
}
Ответ №3:
Попробуйте что-то вроде этого:
Map<String, Set<String>> newFollowsGraph = new HashMap<>();
for (Map.Entry<String, Set<String>> me : followsGraph.entrySet()) {
String key = me.getKey();
Set<String> valueSet = me.getValue();
for (String s : valueSet) {
if (newFollowerGraph.containsKey(s)){
newFollowerGraph.get(s).add(key);
} else {
Set<String> tmp = new LinkedHashSet<>();
tmp.add(key)
newFollowerGraph.put(s, tmp);
}
}
}
Проблема в том, что вы вставляете новые данные в объект, над которым выполняете итерацию.