Показатели хеш-набора и массива

Я реализовал метод, который просто включает цикл CSV файлов, содержащих данные на нескольких разных модулях. Затем добавляется "moduleName" в hashSet. (Код, показанный ниже)

Я использовал hashSet, поскольку он не содержит никаких дубликатов вместо ArrayList, которые должны были бы использовать метод contains() и перебирать список, чтобы проверить, есть ли он там.

Я считаю, что использование хэш-набора имеет лучшую производительность, чем список массивов. Правильно ли я утверждаю, что?

Кроме того, может кто-нибудь объяснить мне:

  • Как работать с производительностью для каждой структуры данных, если используется?
  • Какова сложность использования нотации Big-O?

    HashSet<String> modulesUploaded = new HashSet<String>();
    
    for (File f: marksheetFiles){
        try {
            csvFileReader = new CSVFileReader(f);
            csvReader = csvFileReader.readFile();
            csvReader.readHeaders();
    
            while(csvReader.readRecord()){
                String moduleName = csvReader.get("Module");
    
                if (!moduleName.isEmpty()){
                    modulesUploaded.add(moduleName);
                }
            }
    
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        csvReader.close();
    }
    return modulesUploaded; 
    

    }

Ответ 1

Мой эксперимент показывает, что HashSet быстрее, чем ArrayList, начиная с коллекций из 3 элементов включительно.

Полная таблица результатов

| Boost  |  Collection Size  |
|  2x    |       3 elements  |
|  3x    |      10 elements  |
|  6x    |      50 elements  |
|  12x   |     200 elements  |  <= proportion 532-12 vs 10.000-200 elements
|  532x  |  10.000 elements  |  <= shows linear lookup growth for the ArrayList

Ответ 2

Это совершенно разные классы, поэтому вопрос: какое поведение вы хотите?

HashSet гарантирует отсутствие дубликатов, дает метод O (1) contains(), но не сохраняет порядок.
ArrayList не гарантирует, что дубликатов нет, contains() - O (n), но вы можете управлять порядком записей.

Ответ 3

Я считаю, что использование хэш-набора имеет лучшую производительность, чем список массивов. Правильно ли я утверждаю, что?

С многими (независимо от того, что это означает) записи, да. Однако при небольших размерах данных линейный поиск может быть быстрее, чем хеширование. Где именно безумие, вы должны просто измерить. Я чувствую, что с менее чем 10 элементами, линейный поиск, вероятно, быстрее; с более чем 100 элементами хеширования, вероятно, быстрее, но это только мое чувство...

Поиск из HashSet - это постоянное время, O (1), при условии, что реализация элементов hashCode является разумной. Линейный поиск из списка - это линейное время, O (n).

Ответ 4

Это зависит от использования структуры данных.

Вы сохраняете данные в HashSet, а для вашего случая для хранения HashSet лучше, чем ArrayList (так как вы не хотите дублировать записи). Но просто хранение не является обычным намерением.

Это зависит от того, как вы хотите читать и обрабатывать сохраненные данные. Если вам нужен последовательный доступ или доступ к случайным индексам, тогда ArrayList лучше, или если упорядочение не имеет значения, тогда HashSet лучше.

Если упорядочение имеет значение, но вы хотите сделать много изменений (дополнений и удалений), LinkedList лучше.

Для доступа к определенному элементу HashSet будет иметь временную сложность как O (1), и если бы вы использовали ArrayList, это было бы O (N), как вы сами указали, вам придется iterate через список и посмотреть, нет ли элемента.