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

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

List<String> stringList = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h");
Set<String> stringSet = new HashSet<>(stringList);
System.out.println(stringSet);

На выводе всегда получается тот же порядок "a", "b", "c", "d", "e", "f", "g", "h". Хотя, например, если создать Set через:

Set<String> stringSet = Set.of("a", "b", "c", "d", "e", "f", "g", "h");

... то порядок рандомный.


Ответы (1 шт):

Автор решения: CrazyElf
  1. Почему именно такой порядок вывода элементов у HashSet. Я полагаю, что это из-за того, что значения хэшей латинских символов идут по порядку, соответственно в хэш-таблице эти ключи тоже идут по порядку, в этом же порядке они и выводятся на печать. Проверим hashCode этих символов:
import java.util.Arrays;
import java.util.List;

public class Main
{
    public static void main(String[] args) {
        List<String> stringList = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h");
        for (String ch : stringList) {
            System.out.println(ch.hashCode());
        }
    }
}

Вывод:

97
98
99
100
101
102
103
104

Да, хэш-коды этих символов идут по порядку.

  1. Set.of - это интерфейс, а не конкретный класс, он не говорит, какая реализация множества будет использоваться в реальности (их там несколько), единственное что известно - это то, что она будет неизменяемая. И, судя по всему это не HashSet (он то изменяемый), а что-то другое, поэтому и порядок элементов там произвольный, как вообще-то и полагается для множества.

P.S. Если поменять некоторые символы на русские, они отсортируются в конец при печати, несмотря на то, что размер хэш-массива в данном случае всего 8 и если моя теория верна, остаток от деления на 8 должен был бы дать другой порядок элементов. Такое впечатление, что HashMap делает сортировку ключей по значению (не по хэшу), хотя она там и не заявлена.

→ Ссылка