#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); }
Комментариев нет:
Отправить комментарий