Страницы

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

среда, 29 января 2020 г.

Зачем и в каких конкретно случаях нужно использовать HashMap, если мы можем сделать тоже самое используя HashSet?

#java #map #коллекции #множества


Есть простой класс:

public class Person {
    private int age;
    private String name;

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [age=" + age + ", name=" + name + "]";
    }

}


Есть еще один класс:

public class Item {
    private K key;
    private P person;
    public Item(K key, P person) {
        this.key = key;
        this.person = person;
    }
    public K getKey() {
        return key;
    }
    public void setKey(K key) {
        this.key = key;
    }
    public P getPerson() {
        return person;
    }
    public void setPerson(P person) {
        this.person = person;
    }
    @Override
    public String toString() {
        return "Item [key=" + key + ", person=" + person + "]";
    }


}


ГДЕ ПРАВДА???

И сама реализация классов:

public class Main {
    public static void main(String[] args) {

        Set> set = new HashSet>();

        set.add(new Item(1, new Person(23, "gogo")));
        set.add(new Item(2, new Person(42, "niko")));
        set.add(new Item(3, new Person(32, "toto")));

        Iterator> iter = set.iterator();

        while (iter.hasNext()) {
            System.out.println(iter.next());

        }

        Map map = new HashMap();

        map.put(1, new Person(12, "anton"));
        map.put(2, new Person(42, "valera"));
        map.put(3, new Person(41, "vova"));

        Iterator iter1 = map.entrySet().iterator();

        while (iter1.hasNext()) {
            System.out.println(iter1.next());
        }

    }
}

    


Ответы

Ответ 1



Это принципиально разные структуры данных и используются они для разных целей. Set - это множество, то самое математическое множество. И соответственно использовать его надо как множество, т.е. хранить набор уникальных элементов. Map - это ассоциированный массив, который хранит пары ключ-значение, где ключ должен быть уникальным, а значение нет. Соответственно выбор правильной структуры надо делать на основе того какие действия над этими данными вы собираетесь делать. Если только хранить набор уникальных значений и проверять, что такое значение уже есть в структуре данных, то это Set. Если вам необходимо периодически искать значение по ключу(например по ИД), то это Map. Если же вам надо хранить просто список объектов и периодически проходить по всем элементам этого списка(как в ваших примерах), то надо использовать List. Относительно вопроса о временах операций, есть такие замечательные ссылки, где все хорошо описано для Java: https://github.com/benblack86/java-snippets/blob/master/resources/java_collections.pdf для Абстракций: http://bigocheatsheet.com/ Все они приведены в терминах Big-O нотаций, что это в принципе такое, можно почитать тут.

Ответ 2



Обход всех элементов Map — не самая нужная операция. Самая популярная и важная — быстро получить значение по ключу. Для такого сценария ваш Set не годится: вы не можете это сделать эффективно (не перебирая все ключи). Поэтому Map нужен. Уместнее обратный вопрос: зачем HashSet, если его можно реализовать, например, через HashMap и получить действительно все операции? По факту HashSet примерно так и реализован (он внутри хранит HashMap). Существует он отдельным классом по большей части для удобства. Также замечу, что ваш Item реализован неправильно: даже в вашем сценарии вы не исключаете одинаковый элементов в Set (у вас используется Object.equals и Object.hashCode по умолчанию, соответственно элементы сравниваются по reference equality).

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

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