Страницы

Поиск по вопросам

суббота, 8 февраля 2020 г.

Возможно ли удалить value с даного key в map`e?

#java #map


Есть мапа такого формата:

Map> map;

public qweqwe() {
    this.map = new HashMap>();
}


Туда сохраняются ключи в которых есть несколько значений(Ключи - владельцы животных,
значения - это кличка животного и вид(собака, кошка)).
Нужен метод который будет удалять конкретное животное с конкретного владельца.
Как его организовать?

Вот пример вывода map`ы для общего понимания:

Person [name=Yurii]
       Pet [nickname=Margo, vyd=Dog]
       Pet [nickname=Chita, vyd=Dog]
Person [name=qweqwe]
       Pet [nickname=Chita, vyd=Dog]

    


Ответы

Ответ 1



на Java 8: void remove(Map> map, String name, String nickname) { Maps.filterKeys(map, person -> person.getName().equals(name)).forEach((person, pets) -> { pets.removeIf(pet -> pet.getName().equals(nickname)); }); } Правда, тут оверхед будет, если у вас имена животных уникальны. Вместо pets.removeIf(pet -> pet.getName().equals(nickname)); можно тогда итератор использовать с условием выхода, если очень важен перфоманс. UPD: без Guava будет так: void remove(Map> map, String name, String nickname) { map.entrySet().stream().filter(person -> person.getName().equals(name)).collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue())).forEach((person, pets) -> { pets.removeIf(pet -> pet.getName().equals(nickname)); }); }

Ответ 2



Первое что можно сделать, использовать иную реализацию Map и возможности ООП. Например из пакета com.google.common.collect взять ListMultimap, которая хранит в себе список вида >. Использовать очень просто. Вначале создадим два класса Person и Pet: public class Person { private String name; public Person(String name) { this.name = name; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Person)) return false; Person person = (Person) o; return name != null ? name.equals(person.name) : person.name == null; } @Override public int hashCode() { return name != null ? name.hashCode() : 0; } } public class Pet { private String nickname; private String vyd; Pet(String nickname, String vyd) { this.nickname = nickname; this.vyd = vyd; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Pet)) return false; Pet pet = (Pet) o; if (nickname != null ? !nickname.equals(pet.nickname) : pet.nickname != null) return false; return vyd != null ? vyd.equals(pet.vyd) : pet.vyd == null; } } Обращаю внимание, в классе Person переопределены методы equals и hashCode. В классе Pet переопределен метод equals. Теперь создаем реализацию Multimap: ListMultimap map = ArrayListMultimap.create(); и заполняем данными: Person personFirst = new Person("name1"); map.put(personFirst, new Pet("nick1", "vid1")); map.put(personFirst, new Pet("nick2", "vid2")); map.put(personFirst, new Pet("nick3", "vid3")); Person personSecond = new Person("name2"); map.put(personSecond, new Pet("nick1", "vid1")); map.put(personSecond, new Pet("nick2", "vid2")); map.put(personSecond, new Pet("nick3", "vid3")); теперь чтобы удалить Pet у Person нам необходимы всего лишь экземпляры этих классов: map.remove(personSecond, new Pet("nick3", "vid3")); Также Map можно получить в привычном виде: Map> mapResult = map.asMap(); Если нет возможности использовать стороннюю библиотеку, то можно посмотреть на реализацию методов put и remove в ListMultimap и повторить в упрощенном виде: public boolean put(@Nullable K key, @Nullable V value) { return this.get(key).add(value); } public boolean remove(@Nullable Object key, @Nullable Object value) { Collection collection = (Collection)this.asMap().get(key); return collection != null && collection.remove(value); }

Комментариев нет:

Отправить комментарий