JAVA COLLECTIONS FRAMEWORK » История » Версия 3
Александр Александров, 20.04.2019 23:07
1 | 1 | Александр Александров | h1. JAVA COLLECTIONS FRAMEWORK |
---|---|---|---|
2 | |||
3 | h2. Вопросы |
||
4 | |||
5 | # Что такое Коллекция? |
||
6 | # Назовите основные интерфейсы коллекций и их имплементации. |
||
7 | # Чем отличается ArrayList от LinkedList? В каких случаях лучше использовать первый, а в каких второй? |
||
8 | # Чем отличается HashMap от Hashtable? |
||
9 | # Чем отличается ArrayList от Vector? |
||
10 | # Как сравниваются елементы коллекций? |
||
11 | # Расположите в виде иерархии следующие интерфейсы: List, Set, Map, SortedSet, SortedMap, Collection,Iterable, Iterator, NavigableSet, NavigableMap. |
||
12 | # Почему Map - это не Collection, в то время как List и Set являются Collection? |
||
13 | # Дайте определение понятию "iterator". |
||
14 | # Что вы знаете об интерфейсе Iterable? |
||
15 | # Как одной строчкой преобразовать HashSet в ArrayList? |
||
16 | # Как одной строчкой преобразовать ArrayList в HashSet? |
||
17 | # Как перебрать все ключи Map учитывая, что Map - это не Iterable? |
||
18 | # Как перебрать все значения Map учитывая, что Map - это не Iterable? |
||
19 | # Как перебрать все пары ключ-значение в Map учитывая, что Map - это не Iterable? |
||
20 | # В чем проявляется "сортированность" SortedMap, кроме того, что toString() выводит все по порядку? |
||
21 | # Как одним вызовом копировать элементы из любой Collection в массив? |
||
22 | # Реализуйте симметрическую разность двух коллекций используя методы Collection(addAll(), removeAll(), retainAll()). |
||
23 | # Сравните Enumeration и Iterator. |
||
24 | # Как между собой связаны Iterable и Iterator? |
||
25 | # Как между собой связаны Iterable, Iterator и "for-each " введенный в Java 5? |
||
26 | # Сравните Iterator и ListIterator. |
||
27 | # Что произойдет, если я вызову Iterator.next() не "спросив" Iterator.hasNext()? |
||
28 | # Что произойдет, если я вызову Iterator.next() перед этим 10 раз вызвав Iterator.hasNext()? Я пропущу 9 элементов? |
||
29 | # Если у меня есть коллекция и порожденный итератор, изменится ли коллекция, если я вызову iterator.remove()? |
||
30 | # Если у меня есть коллекция и порожденный итератор, изменится ли итератор, если я вызову collection.remove(..)? |
||
31 | # Зачем добавили ArrayList, если уже был Vector? |
||
32 | # В реализации класса ArrayList есть следующие поля: Object[] elementData, int size. |
||
33 | # Объясните, зачем хранить отдельно size, если всегда можно взять elementData.length? |
||
34 | # LinkedList - это односвязный, двусвязный или четырехсвязный список? |
||
35 | # Какое худшее время работы метода contain() для элемента, который есть в LinkedList (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
36 | # Какое худшее время работы метода contain() для элемента, который есть в ArrayList (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
37 | # Какое худшее время работы метода add() для LinkedList (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
38 | # Какое худшее время работы метода add() для ArrayList (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
39 | # Сколько выделяется элементов в памяти при вызове ArrayList.add()? |
||
40 | # Сколько выделяется элементов в памяти при вызове LinkedList.add()? |
||
41 | # Оцените количество памяти на хранение одного примитива типа byte в LinkedList? |
||
42 | # Оцените количество памяти на хранение одного примитива типа byte в ArrayList? |
||
43 | # Я добавляю элемент в середину List-а: list.add(list.size()/2, newElem). Для кого эта операция медленнее - для ArrayList или для LinkedList? |
||
44 | # Как перебрать элементы LinkedList в обратном порядке, не используя медленный get(index)? |
||
45 | # Как одним вызовом из List получить List со всеми элементами, кроме первых и последних 3-х? |
||
46 | # Могут ли у разных объектов в памяти (ref0 != ref1) быть ref0.hashCode() == ref1.hashCode()? |
||
47 | # Могут ли у разных объектов в памяти (ref0 != ref1) быть ref0.equals(ref1) == true? |
||
48 | # Могут ли у разных ссылок на один объект в памяти (ref0 == ref1) быть ref0.equals(ref1) == false? |
||
49 | # Есть класс Point{int x, y;}. Почему хэш-код в виде 31 * x + y предпочтительнее чем x + y? |
||
50 | # Если у класса Point{int x, y;} "правильно " реализовать метод equals (return ref0.x == ref1.x && ref0.y == ref1.y), но сделать хэш-код в виде int hashCode() {return x;}, то будут ли корректно такие точки помещаться и извлекаться из HashSet? |
||
51 | # equals() порождает отношение эквивалентности. Какими из свойств обладает такое отношение: коммутативность, симметричность, рефлексивность, дистрибутивность, ассоциативность, транзитивность? |
||
52 | # Можно ли так реализовать equals(Object that) {return this.hashCode() == that.hashCode()}? |
||
53 | # В equals требуется проверять, что аргумент (equals(Object that)) такого же типа как и сам объект. В чем разница между this.getClass() == that.getClass() и that instanceof MyClass? |
||
54 | # Можно ли реализовать метод equals класса MyClass вот так: class MyClass {public boolean equals(MyClass that) {return this == that;}}? |
||
55 | # Будет ли работать HashMap, если все ключи будут возвращать int hashCode() {return 42;}? |
||
56 | # Зачем добавили HashMap, если уже был Hashtable? |
||
57 | # Согласно Кнуту и Кормену существует две основных реализации хэш-таблицы: на основе открытой адресацией и на основе метода цепочек. Как реализована HashMap? Почему так сделали (по вашему мнению)? В чем минусы и плюсы каждого подхода? |
||
58 | # Сколько переходов по ссылкам происходит, когда вы делаете HashMap.get(key) по ключу, который есть в таблице? |
||
59 | # Сколько создается новых объектов, когда вы добавляете новый элемент в HashMap? |
||
60 | # Как работает HashMap при попытке сохранить в нее два элемента по ключам с |
||
61 | # одинаковым hashCode, но для которых equals == false? |
||
62 | # HashMap может выродиться в список даже для ключей с разным hashCode. Как это возможно? |
||
63 | # Какое худшее время работы метода get(key) для ключа, которого нет в таблице (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
64 | # Какое худшее время работы метода get(key) для ключа, который есть в таблице (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
65 | # Объясните смысл параметров в конструкторе HashMap(int initialCapacity, float loadFactor). |
||
66 | # В чем разница между HashMap и IdentityHashMap? Для чего нужна IdentityHashMap? Как может быть полезна для реализации сериализации или клонирования? |
||
67 | # В чем разница между HashMap и WeakHashMap? Для чего нужна WeakHashMap? |
||
68 | # В WeakHashMap используются WeakReferences. А почему бы не создать SoftHashMap на SoftReferences? |
||
69 | # В WeakHashMap используются WeakReferences. А почему бы не создать PhantomHashMap на PhantomReferences? |
||
70 | # Сделайте HashSet из HashMap (используйте только множество ключей, но не множество значений). |
||
71 | # Сделайте HashMap из HashSet (HashSet<Map.Entry<K, V>>) |
||
72 | # Сравните интерфейсы java.util.Queue и java.util.Deque. |
||
73 | # Кто кого расширяет: Queue расширяет Deque, или Deque расширяет Queue? |
||
74 | # Почему LinkedList реализует и List, и Deque? |
||
75 | # В чем разница между классами java.util.Arrays и java.lang.reflect.Array? |
||
76 | # В чем разница между классами java.util.Collection и java.util.Collections? |
||
77 | # Напишите НЕмногопоточную программу, которая заставляет коллекцию выбросить ConcurrentModificationException. |
||
78 | # Что такое "fail-fast поведение"? |
||
79 | # Для множеств еnum-ов есть специальный класс java.util.EnumSet? Зачем? Чем авторов не устраивал HashSet или TreeSet? |
||
80 | # java.util.Stack - считается "устаревшим". Чем его рекомендуют заменять? Почему? |
||
81 | # Какая коллекция реализует дисциплину обслуживания FIFO? |
||
82 | # Какая коллекция реализует дисциплину обслуживания FILO? |
||
83 | # Приведите пример, когда какая-либо коллекция выбрасывает UnsupportedOperationException. |
||
84 | # Почему нельзя написать "ArrayList<List> numbers = new ArrayList<ArrayList>();" но можно "List<ArrayList> numbers = new ArrayList<ArrayList>();"? |
||
85 | # LinkedHashMap - что это еще за "зверь"? Что в нем от LinkedList, а что от HashMap? |
||
86 | # LinkedHashSet - что это еще за "зверь"? Что в нем от LinkedList, а что от HashSet? |
||
87 | # Говорят, на LinkedHashMap легко сделать простенький кэш c "invalidation policy", знаете как? |
||
88 | # Что позволяет сделать PriorityQueue? |
||
89 | # В чем заключаются отличия java.util.Comparator от java.lang.Comparable? |
||
90 | |||
91 | h2. Ответы |
||
92 | |||
93 | h3. Что такое Коллекция? |
||
94 | |||
95 | 2 | Александр Александров | Коллекции - это хранилища или контейнеры, поддерживающие различные способы накопления и упорядочения объектов с целью обеспечения возможностей эффективного доступа к ним. Они представляют собой реализацию абстрактных структур данных, поддерживающих три основные операции: |
96 | 1 | Александр Александров | |
97 | 2 | Александр Александров | * добавление нового элемента в коллекцию; |
98 | * удаление элемента из коллекции; |
||
99 | * изменение элемента в коллекции. |
||
100 | |||
101 | 1 | Александр Александров | h3. Назовите основные интерфейсы коллекций и их имплементации. |
102 | |||
103 | 2 | Александр Александров | {{dmsf_image(199)}} |
104 | 1 | Александр Александров | |
105 | 2 | Александр Александров | Сollection расширяет три интерфейса: *List* , *Set* , *Queue* . |
106 | |||
107 | *List* - хранит упорядоченные елементы(могут быть одинаковые); Имеет такие реализации как _LinkedList_, _ArrayList_ и _Vector_. |
||
108 | |||
109 | * Vector синхронизирован, и по этому в одном потоке, он работает медленней остальных реализаций. |
||
110 | * ArrayList - его преимущество в навигации по коллекции. |
||
111 | * LinkedList - его преимущество в во вставке и удалении элементов в коллекции. |
||
112 | |||
113 | *Set* - коллекции, которые не содержат повторяющихся элементов. Основные реализации: _HashSet_, _TreeSet_, _LinkedHashSet_ |
||
114 | |||
115 | * TreeSet - упорядочивает элементы по их значениям; |
||
116 | * HashSet - упорядочивает элементы по их хэш ключах, хотя на первый взляд может показаться что элементы хранятся в случайном порядке. |
||
117 | * LinkedHashSet - хранит элементы в порядке их добавления. |
||
118 | |||
119 | *Queue* - интерфейс для реализации очереди в java. Основные реализации: _LinkedList_, _PriorityQueue_. Очереди работают по принципу FIFO – First in First out. |
||
120 | |||
121 | *Map* - интерфейс для реализации так называемой карты, где элементы хранятся с их ключами. Основные реализации: _HashTable_, _HashMap_, _TreeMap_, _LinkedHashMap_ |
||
122 | |||
123 | * HashTable - синхронизированна, объявлена уставревшей. |
||
124 | * HashMap - порядок елементов рассчитывается по хэш ключу; |
||
125 | * TreeMap - элементы хранятся в отсортированном порядке |
||
126 | * LinkedHashMap - элементы хранятся в порядке вставки |
||
127 | |||
128 | *%{color: red}Ключи в Мар не могут быть одинаковыми!%* |
||
129 | |||
130 | Синхронизировать не синхронизированные коллекции и карты можно посредством класса Collections.synchronizedMap(MyMap)\synchronizedList(MyList). |
||
131 | |||
132 | 1 | Александр Александров | h3. Чем отличается ArrayList от LinkedList? В каких случаях лучше использовать первый, а в каких второй? |
133 | |||
134 | 2 | Александр Александров | Отличие заключается в способе хранения данных. ArrayList хранит в виде массива, а LinkedList - в виде списка (двунаправленного). |
135 | В ArrayList быстрее происходит сортировка, т.к. для ее выполнения данные списка копируются в массив (а копировать из массива ArrayList в массив для сортировки быстрее). При большом числе операций добавления и удаления LinkedList должен быть более удачным выбором, т.к. при этих операциях не приходится перемещать части массива. |
||
136 | Если при добавлении в ArrayList превышается его объем, размер массива увеличивается, новая емкость рассчитывается по формуле (oldCapacity * 3) / 2 + 1, поэтому лучше указывать размер при создании или, если он не известен, использовать LinkedList (но это может быть существенно при слишком уж больших объемах данных). |
||
137 | 1 | Александр Александров | |
138 | h3. Чем отличается HashMap от Hashtable? |
||
139 | |||
140 | 2 | Александр Александров | Класс HashMap по функционалу очень похож на Hashtable. Главное отличие в том, что методы класса Hashtable синхронизированы, а HashMap - нет. Кроме этого класс HashMap в отличии от Hashtable разрешает использование null в качестве ключей и значений. |
141 | Наличие синхронизации в Hashtable уменьшает производительность кода, использующего данный класс. Поэтому классы JCF (Java Collections Framework, появившийся в Java 2), в том числе и HashMap, несинхронизированы. Если синхронизация все же нужна, можно использовать методы класса Collections: Collections.synchronizedMap(map), Collections.synchronizedList(list) или Collections.synchronizedSet(set). |
||
142 | Данные методы возвращают синхронизированный декоратор переданной коллекции. При этом все равно в случае итерирования по коллекции требуется ручная синхронизация. Начиная с Java 6 JCF был расширен специальными коллекциями, поддерживающими многопоточный доступ, такими как CopyOnWriteArrayList и ConcurrentHashMap. |
||
143 | 1 | Александр Александров | |
144 | h3. Чем отличается ArrayList от Vector? |
||
145 | |||
146 | 2 | Александр Александров | Методы класса Vector синхронизированы, в то время как ArrayList - нет. |
147 | 1 | Александр Александров | |
148 | 2 | Александр Александров | h3. Как сравниваются элементы коллекций? |
149 | 1 | Александр Александров | |
150 | 2 | Александр Александров | Для сравнения элементов коллекций используется метод equals() и hashcode();Эти методы унаследованы от класса Object. |
151 | 1 | Александр Александров | |
152 | 2 | Александр Александров | * Если наш пользовательский класс переопределяет equals(), то он должен и переопределить hashcode(). |
153 | * Если два объекта эквивалентны, то и хэш коды этих объектов тоже должны быть равны. |
||
154 | * Если поле не используется в equals(), то оно и не должно использоваться в hashcode(). |
||
155 | |||
156 | 1 | Александр Александров | h3. Расположите в виде иерархии следующие интерфейсы: List, Set, Map, SortedSet, SortedMap, Collection,Iterable, Iterator, NavigableSet, NavigableMap. |
157 | |||
158 | 2 | Александр Александров | {{dmsf_image(200)}} |
159 | 1 | Александр Александров | |
160 | h3. Почему Map - это не Collection, в то время как List и Set являются Collection? |
||
161 | |||
162 | 2 | Александр Александров | Коллекция (List и Set) представляет собой совокупность некоторых элементов (обычно экземпляров одного класса). Map -это совокупность пар "ключ"-"значение". |
163 | Соответственно некоторые методы интерфейса Collection нельзя использовать в Map. Например, метод remove(Object o) в интерфейсе Collection предназначен для удаления элемента, тогда как такой же метод remove(Object key) в интерфейсе Map - удаляет элемент по заданному ключу. |
||
164 | 1 | Александр Александров | |
165 | h3. Дайте определение понятию "iterator". |
||
166 | |||
167 | 2 | Александр Александров | Итератор - объект, позволяющий перебирать элементы коллекции. Например foreach реализован с использованием итератора. Одним из ключевых методов интерфейса Collection является метод Iterator<E> iterator(). Он возвращает итератор - то есть объект, реализующий интерфейс Iterator. Интерфейс Iterator имеет следующее определение: |
168 | 1 | Александр Александров | |
169 | 2 | Александр Александров | <pre><code class="java"> |
170 | public interface Iterator <E> { |
||
171 | E next; |
||
172 | boolean hasNext(); |
||
173 | void remove(); |
||
174 | } |
||
175 | </code></pre> |
||
176 | 1 | Александр Александров | |
177 | h3. Что вы знаете об интерфейсе Iterable? |
||
178 | |||
179 | 2 | Александр Александров | Все коллекции из java.util реализуют интерфейс Collection, который, в свою очередь, расширяет интерфейс Iterable. В интерфейсе Iterable описан только один метод: _Iterator iterator();_ |
180 | Он возвращает Iterator, т.е. объект, который поочерёдно возвращает все элементы коллекции. |
||
181 | 1 | Александр Александров | |
182 | h3. Как одной строчкой преобразовать HashSet в ArrayList? |
||
183 | |||
184 | 2 | Александр Александров | <pre><code class="java"> |
185 | public static void main(String[] args) { |
||
186 | Set<String> set = new HashSet<>(); |
||
187 | set.add("A"); |
||
188 | set.add("B"); |
||
189 | List<String> list = new ArrayList<>(set); |
||
190 | } |
||
191 | </code></pre> |
||
192 | 1 | Александр Александров | |
193 | h3. Как одной строчкой преобразовать ArrayList в HashSet? |
||
194 | |||
195 | 2 | Александр Александров | <pre><code class="java"> |
196 | public static void main(String[] args) { |
||
197 | List<String> list = new ArrayList<>(); |
||
198 | list.add("A"); |
||
199 | list.add("B"); |
||
200 | Set<String> set = new HashSet<>(list); |
||
201 | } |
||
202 | </code></pre> |
||
203 | 1 | Александр Александров | |
204 | h3. Как перебрать все ключи Map учитывая, что Map - это не Iterable? |
||
205 | |||
206 | 2 | Александр Александров | Использовать метод keySet(), который возвращает множество (Set<K>) ключей. |
207 | 1 | Александр Александров | |
208 | h3. Как перебрать все значения Map учитывая, что Map - это не Iterable? |
||
209 | |||
210 | 2 | Александр Александров | Использовать метод values(), который возвращает коллекцию (Collection<V>) значений. |
211 | 1 | Александр Александров | |
212 | h3. Как перебрать все пары ключ-значение в Map учитывая, что Map - это не Iterable? |
||
213 | |||
214 | 2 | Александр Александров | Использовать метод entrySet(), который возвращает множество (Set<Map.Entry<K, V>) пар "ключ"-"значение". |
215 | 1 | Александр Александров | |
216 | h3. В чем проявляется "сортированность" SortedMap, кроме того, что toString() выводит все по порядку? |
||
217 | |||
218 | 2 | Александр Александров | Естественное упорядочивание (natural ordering) отражается при итерации по коллекции ключей или значений хэш-таблицы (возвращаемых методами keySet(), values() и entrySet()). |
219 | 1 | Александр Александров | |
220 | h3. Как одним вызовом копировать элементы из любой Collection в массив? |
||
221 | |||
222 | 2 | Александр Александров | <pre><code class="java"> |
223 | public static void main(String[] args) { |
||
224 | List<String> list = new ArrayList<>(); |
||
225 | list.add("A"); |
||
226 | list.add("B"); |
||
227 | String[] strArray = list.toArray(new String[list.size()]); |
||
228 | // или |
||
229 | Object[] objArray = list.toArray(); |
||
230 | } |
||
231 | </code></pre> |
||
232 | 1 | Александр Александров | |
233 | h3. Реализуйте симметрическую разность двух коллекций используя методы Collection(addAll(), removeAll(), retainAll()). |
||
234 | |||
235 | 2 | Александр Александров | Симметрическая разность двух коллекций - это множество элементов, одновременно не принадлежащих обоим исходным коллекциям. |
236 | 1 | Александр Александров | |
237 | 2 | Александр Александров | {{dmsf_image(201)}} |
238 | 1 | Александр Александров | |
239 | h3. Сравните Enumeration и Iterator. |
||
240 | |||
241 | 2 | Александр Александров | Оба интерфейса предназначены для обхода коллекций. Интерфейс Iterator был введен несколько позднее в Java Collections Framework и его использование предпочтительнее. Основные различия Iterator по сравнению с Enumeration: |
242 | 1 | Александр Александров | |
243 | 2 | Александр Александров | * наличие метода remove() для удаления элемента из коллекции при обходе; |
244 | * исправлены имена методов для повышения читаемости кода. |
||
245 | 1 | Александр Александров | |
246 | h3. Как между собой связаны Iterable и Iterator? |
||
247 | |||
248 | 2 | Александр Александров | Интерфейс Iterable имеет только один метод - iterator(), который возвращает итератор коллекции для её обхода. |
249 | 1 | Александр Александров | |
250 | h3. Как между собой связаны Iterable, Iterator и "for-each " введенный в Java 5? |
||
251 | |||
252 | 2 | Александр Александров | Экземпляры классов, реализующих интерфейс Iterable, могут использоваться в конструкции foreach |
253 | 1 | Александр Александров | |
254 | h3. Сравните Iterator и ListIterator. |
||
255 | |||
256 | 2 | Александр Александров | ListIterator расширяет интерфейс Iterator, позволяя клиенту осуществлять обход коллекции в обоих направлениях, изменять коллекцию и получать текущую позицию итератора. При этом важно помнить, что ListIterator не указывает на конкретный элемент, а его текущая позиция располагается между элементами, которые возвращают методы previous() и next(). Таким образом, модификация коллекции осуществляется для последнего элемента, который был возвращен методами previous() и next(). |
257 | 1 | Александр Александров | |
258 | h3. Что произойдет, если я вызову Iterator.next() не "спросив" Iterator.hasNext()? |
||
259 | |||
260 | 2 | Александр Александров | Если итератор указывает на последний элемент коллекции, то возникнет исключение NoSuchElementException, иначе будет возвращен следующий элемент. |
261 | 1 | Александр Александров | |
262 | h3. Что произойдет, если я вызову Iterator.next() перед этим 10 раз вызвав Iterator.hasNext()? Я пропущу 9 элементов? |
||
263 | |||
264 | 2 | Александр Александров | Нет, hasNext() осуществляет только проверку наличия следующего элемента. |
265 | 1 | Александр Александров | |
266 | h3. Если у меня есть коллекция и порожденный итератор, изменится ли коллекция, если я вызову iterator.remove()? |
||
267 | |||
268 | 2 | Александр Александров | Вызов метода iterator.remove() возможен только после вызова метода iterator.next() хотя бы раз, иначе появится исключение IllegalStateException(). Если iterator.next() был вызван прежде, то iterator.remove() удалит элемент, на который указывает итератор. |
269 | 1 | Александр Александров | |
270 | h3. Если у меня есть коллекция и порожденный итератор, изменится ли итератор, если я вызову collection.remove(..)? |
||
271 | |||
272 | 2 | Александр Александров | Итератор не изменится, но при следующем вызове его методов возникнет исключение ConcurrentModiÙcationException. |
273 | 1 | Александр Александров | |
274 | h3. Зачем добавили ArrayList, если уже был Vector? |
||
275 | |||
276 | 2 | Александр Александров | Обе структуры данных предназначены для хранения коллекции элементов, в том числе дубликатов и null. Они основаны на использовании массивов, динамически расширяющихся при необходимости. Класс Vector был введен в JDK 1.0 и не является частью Java Collection Framework. Методы класса Vector синхронизированы, что обеспечивает потокобезопасность, но это приводит к снижению производительности, поэтому и был введен класс ArrayList, методы которого не синхронизированы. |
277 | 1 | Александр Александров | |
278 | 3 | Александр Александров | h3. В реализации класса ArrayList есть следующие поля: Object[] elementData, int size. Объясните, зачем хранить отдельно size, если всегда можно взять elementData.length? |
279 | 1 | Александр Александров | |
280 | 2 | Александр Александров | Размер массива elementData представляет собой вместимость (capacity) ArrayList, которая всегда больше переменной size - реального количества хранимых элементов. С добавлением новых элементов вместимость автоматически возрастает при необходимости. |
281 | 1 | Александр Александров | |
282 | 3 | Александр Александров | h3. LinkedList - это односвязный, двусвязный или четырехсвязный список? |
283 | 1 | Александр Александров | |
284 | Двухсвязный список: каждый элемент LinkedList хранит ссылку на предыдущий и следующий элементы. |
||
285 | |||
286 | h3. Какое худшее время работы метода contain() для элемента, который есть в LinkedList (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
287 | |||
288 | 3 | Александр Александров | O(N). Время поиска элемента линейно пропорционально количеству элементов с списке. |
289 | 1 | Александр Александров | |
290 | h3. Какое худшее время работы метода contain() для элемента, который есть в ArrayList (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
291 | |||
292 | 3 | Александр Александров | O(N). Время поиска элемента линейно пропорционально количеству элементов с списке. |
293 | 1 | Александр Александров | |
294 | h3. Какое худшее время работы метода add() для LinkedList (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
295 | |||
296 | 3 | Александр Александров | O(N). Здесь стоит заметить, что добавление элемента в конец списка с помощью методом add(value), addLast(value) и добавление в начало списка с помощью addFirst(value) выполняется за время O(1). O(N) - будет при добавление элемента в отсортированный список, а также при добавлении элемента с помощью метода add(index, value) |
297 | 1 | Александр Александров | |
298 | h3. Какое худшее время работы метода add() для ArrayList (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
299 | |||
300 | 3 | Александр Александров | O(N). Вставка элемента в конец списка осуществляется за время O(1), но если вместимость массива недостаточна, то происходит создание нового массива с увеличенным размером и копирование всех элементов из старого массива в новый. |
301 | 1 | Александр Александров | |
302 | h3. Сколько выделяется элементов в памяти при вызове ArrayList.add()? |
||
303 | |||
304 | 3 | Александр Александров | Если в массиве достаточно места для размещения нового элемента, то дополнительное место в памяти не выделяется. Иначе происходит создание нового массива с размером: |
305 | 1 | Александр Александров | |
306 | 3 | Александр Александров | <pre> |
307 | int oldCapacity = elementData.length; |
||
308 | int newCapacity = oldCapacity + (oldCapacity >> 1); |
||
309 | </pre> |
||
310 | 1 | Александр Александров | |
311 | 3 | Александр Александров | Другими словами, создается новый массив, размер которого вычисляется как умножение старого размера на 1.5 (это верно для JDK 1.7, в более ранних версиях вычисления отличаются). |
312 | |||
313 | 1 | Александр Александров | h3. Сколько выделяется элементов в памяти при вызове LinkedList.add()? |
314 | |||
315 | 3 | Александр Александров | Создается один новый экземпляр вложенного класса Node. |
316 | 1 | Александр Александров | |
317 | h3. Оцените количество памяти на хранение одного примитива типа byte в LinkedList? |
||
318 | |||
319 | 3 | Александр Александров | Каждый элемент LinkedList хранит ссылку на предыдущий элемент, следующий элемент и ссылку на данные. Для x32 систем каждая ссылка занимает 32 бита (4 байта). Сам объект типа Node занимает приблизительно 8 байт. Размер каждого объекта в Java кратен 8, соответственно получаем 24 байта. Примитив типа byte занимает 1 байт памяти, но в списке примитивы упаковываются, соответственно получаем еще 8 байт. Таким образом, в x32 JVM около 32 байтоввыделяется для хранения одного значения типа byte в LinkedList. Для 64-битной JVM каждая ссылка занимает 64 бита (8 байт). Вычисления аналогичны. |
320 | 1 | Александр Александров | |
321 | h3. Оцените количество памяти на хранение одного примитива типа byte в ArrayList? |
||
322 | |||
323 | 3 | Александр Александров | ArrayList основан на массиве. Каждый элемент массива хранит примитивный тип данных - byte, размер которого 1 байт. |
324 | 1 | Александр Александров | |
325 | h3. Я добавляю элемент в середину List-а: list.add(list.size()/2, newElem). Для кого эта операция медленнее - для ArrayList или для LinkedList? |
||
326 | |||
327 | 3 | Александр Александров | Для ArrayList: |
328 | 1 | Александр Александров | |
329 | 3 | Александр Александров | * проверка массива на вместимость. Если вместимости недостаточно, то увеличение размера массива и копирование всех элементов в новый массив ( O(N) ); |
330 | * копирование всех элементов, расположенных правее от позиции вставки, на одну позицию вправо ( O(N/2)); |
||
331 | * вставка элемента ( O(1) ). |
||
332 | 1 | Александр Александров | |
333 | 3 | Александр Александров | Для LinkedList: |
334 | 1 | Александр Александров | |
335 | 3 | Александр Александров | * поиск позиции вставки ( O(N/2) ); |
336 | * вставка элемента ( O(1) ). |
||
337 | 1 | Александр Александров | |
338 | 3 | Александр Александров | В худшем случае вставка в середину списка эффективнее для LinkedList. В остальных - скорее всего, для ArrayList, поскольку копирование элементов осуществляется за счет системного метода System.arraycopy(). |
339 | 1 | Александр Александров | |
340 | 3 | Александр Александров | h3. Как перебрать элементы LinkedList в обратном порядке, не используя медленный get(index)? |
341 | |||
342 | Использовать обратный итератор. Для этого в LinkedList есть метод descendingIterator(). |
||
343 | |||
344 | 1 | Александр Александров | h3. Как одним вызовом из List получить List со всеми элементами, кроме первых и последних 3-х? |
345 | |||
346 | 3 | Александр Александров | <pre> |
347 | List<Integer> sourceList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9)); |
||
348 | List<Integer> subList = sourceList.subList(3, sourceList.size() - 3); |
||
349 | </pre> |
||
350 | 1 | Александр Александров | |
351 | |||
352 | h3. Могут ли у разных объектов в памяти (ref0 != ref1) быть ref0.hashCode() == ref1.hashCode()? |
||
353 | |||
354 | 3 | Александр Александров | Да, могут. Метод hashCode() не гарантирует уникальность возвращаемого значения. |
355 | 1 | Александр Александров | |
356 | h3. Могут ли у разных объектов в памяти (ref0 != ref1) быть ref0.equals(ref1) == true? |
||
357 | |||
358 | 3 | Александр Александров | Да, могут. Для этого в классе этих объектов должен быть переопределен метод equals(). Если используется метод Object.equals(), то для двух ссылок x и y метод вернет true тогда и только тогда, когда обе ссылки указывают на один и тот же объект (т.е. x == y возвращает true). |
359 | 1 | Александр Александров | |
360 | h3. Могут ли у разных ссылок на один объект в памяти (ref0 == ref1) быть ref0.equals(ref1) == false? |
||
361 | |||
362 | 3 | Александр Александров | Нет, не может. Метод equals() должен гарантировать свойство рефлексивности: для любых ненулевых ссылок xметод x.equals(x) должен возвращать true. |
363 | 1 | Александр Александров | |
364 | h3. Есть класс Point{int x, y;}. Почему хэш-код в виде 31 * x + y предпочтительнее чем x + y? |
||
365 | |||
366 | 3 | Александр Александров | Множитель создает зависимость значения хэш-кода от очередности обработки полей, а это дает гораздо лучшую хэш-функцию. |
367 | 1 | Александр Александров | |
368 | h3. Если у класса Point{int x, y;} "правильно " реализовать метод equals (return ref0.x == ref1.x && ref0.y == ref1.y), но сделать хэш-код в виде int hashCode() {return x;}, то будут ли корректно такие точки помещаться и извлекаться из HashSet? |
||
369 | |||
370 | 3 | Александр Александров | HashSet использует HashMap для хранения элементов (в качестве ключа используется сам объект). При добавлении элемента в HashMap вычисляется хэшкод и позиция в массиве, куда будет вставлен новый элемент. У всех экземпляров класса Point одинаковый хэшкод, что приводит в вырождению хэш-таблицы в список. При возникновении коллизии осуществляется проверка на наличие уже такого элемента в текущем списке: |
371 | 1 | Александр Александров | |
372 | 3 | Александр Александров | <pre> |
373 | e.hash == hash && ((k = e.key) == || key.equals(k)) |
||
374 | </pre> |
||
375 | 1 | Александр Александров | |
376 | 3 | Александр Александров | Если элемент найден, то его значение перезаписывается. В нашем случае для разных объектов метод equals() будет возвращать false. Соответственно новый элемент будет добавлен в HashSet. Извлечение элемента также будет осуществляться успешно. Но производительность такого кода будет низкой и преимущества хэштаблиц использоваться не будут. |
377 | |||
378 | 1 | Александр Александров | h3. equals() порождает отношение эквивалентности. Какими из свойств обладает такое отношение: коммутативность, симметричность, рефлексивность, дистрибутивность, ассоциативность, транзитивность? |
379 | |||
380 | 3 | Александр Александров | Метод equals() должен обеспечивать: |
381 | 1 | Александр Александров | |
382 | 3 | Александр Александров | * симметричность (для любых ненулевых ссылок x и y метод x.equals(y) должен возвращать true тогда и только тогда, когда y.equals(x) возвращает true); |
383 | * рефлексивность (для любых ненулевых ссылок x метод x.equals(x) должен возвращать true.); |
||
384 | * транзитивность (для любых ненулевых ссылок x, y и z, если x.equals(y) возвращает true и y.equals(z)возвращает true, тогда и x.equals(z) должен возвращать true). |
||
385 | 1 | Александр Александров | |
386 | 3 | Александр Александров | Также есть ещё два свойства: постоянство и неравенство null. |
387 | |||
388 | 1 | Александр Александров | h3. Можно ли так реализовать equals(Object that) {return this.hashCode() == that.hashCode()}? |
389 | |||
390 | 3 | Александр Александров | Строго говоря нельзя, поскольку метод hashCode() не гарантирует уникальность значения для каждого объекта. Однако для сравнения экземпляров класса Object такой код допустим, т.к. метод hashCode() в классе Object возвращает уникальные значения для разных объектов (вычисления основаны на использовании адреса объекта в памяти). |
391 | 1 | Александр Александров | |
392 | h3. В equals требуется проверять, что аргумент (equals(Object that)) такого же типа как и сам объект. В чем разница между this.getClass() == that.getClass() и that instanceof MyClass? |
||
393 | |||
394 | 3 | Александр Александров | Оператор instanceof сравнивает объект и указанный тип. Его можно использовать для проверки является ли данный объект экземпляром некоторого класса, либо экземпляром его дочернего класса, либо экземпляром класса, который реализует указанный интерфейс. getClass() = ... проверяет два типа на идентичность. Для корректной реализации контракта метода equals() необходимо использовать точное сравнение с помощью getClass(). |
395 | 1 | Александр Александров | |
396 | h3. Можно ли реализовать метод equals класса MyClass вот так: class MyClass {public boolean equals(MyClass that) {return this == that;}}? |
||
397 | |||
398 | 3 | Александр Александров | Реализовать можно, но данный метод не переопределяет метод equals() класса Object, а перегружает его. |
399 | 1 | Александр Александров | |
400 | h3. Будет ли работать HashMap, если все ключи будут возвращать int hashCode() {return 42;}? |
||
401 | |||
402 | 3 | Александр Александров | Да, будет. Но тогда хэш-таблица вырождается в связный список и теряет свои преимущества. |
403 | 1 | Александр Александров | |
404 | h3. Зачем добавили HashMap, если уже был Hashtable? |
||
405 | |||
406 | 3 | Александр Александров | Класс Hashtable был введен в JDK 1.0 и не является частью Java Collection Framework. Методы класса Hashtable синхронизированы, что обеспечивает потокобезопасность, но это приводит к снижению производительности, поэтому и был введен класс HashMap, методы которого не синхронизированы. |
407 | Помимо этого класс HashMap обладает некоторыми другими отличиями: например, позволяет хранить один null ключ и множество null значений. |
||
408 | 1 | Александр Александров | |
409 | h3. Согласно Кнуту и Кормену существует две основных реализации хэш-таблицы: на основе открытой адресацией и на основе метода цепочек. Как реализована HashMap? Почему так сделали (по вашему мнению)? В чем минусы и плюсы каждого подхода? |
||
410 | |||
411 | 3 | Александр Александров | Класс HashMap реализован с использованием метода цепочек, т.е. каждой ячейке массива соответствует свой связный список и при возникновении коллизии осуществляется добавление нового элемента в этот список. Для метода цепочек коэффициент заполнения может быть больше 1, с увеличением числа элементов производительность убывает линейно. Такие таблицы удобно использовать, если заранее неизвестно количество хранимых элементов, либо их может быть достаточно много, что приводит к большим значениям коэффициента заполнения. Среди методов открытой реализации различают: |
412 | 1 | Александр Александров | |
413 | 3 | Александр Александров | * линейное пробирование; |
414 | * квадратичное пробирование; |
||
415 | * двойное хеширование. |
||
416 | |||
417 | Основные недостатки структур с методом открытой адресации: |
||
418 | |||
419 | * Количество элементов в таблице не может превышать размера массива. По мере увеличения числа элементов в таблице и повышения коэффициента заполнения (load factor) производительность структуры резко падает, поэтому необходимо проводить перехеширование. |
||
420 | * Сложно организовать удаление элемента. |
||
421 | * Также первые два метода открытой адресации приводят к проблеме первичной и вторичной группировок. |
||
422 | |||
423 | Основное преимущество хэш-таблицы с открытой адресацией - это отсутствие затрат на создание и хранение объектов списка. Также проще организовать сериализацию/десериализацию объекта. |
||
424 | |||
425 | 1 | Александр Александров | h3. Сколько переходов по ссылкам происходит, когда вы делаете HashMap.get(key) по ключу, который есть в таблице? |
426 | |||
427 | 3 | Александр Александров | Возможно, я неправильно понял этот вопрос. За переходы по ссылке в данном ответе я считаю вызовы методов. |
428 | 1 | Александр Александров | |
429 | 3 | Александр Александров | {{dmsf_image(204)}} |
430 | |||
431 | Рассмотрим первый случай, когда ключ равен null: выполняем метод getForNullKey(). |
||
432 | |||
433 | {{dmsf_image(203)}} |
||
434 | |||
435 | В цикле foreach проходимся по списку значений для ключа и возвращаем нужное значение. Таким образом, получаем 1 переход. Второй случай: ключ не равен null. Выполняем метод getEntry(key). |
||
436 | |||
437 | {{dmsf_image(202)}} |
||
438 | |||
439 | Вычисляется хэш-код ключа (метод hash(key)), затем определяется индекс ячейки массива, в которой будем искать значение (метод indexFor(hash, table.length)). После того, как нашли нужную пару "ключ-значение" возвращаем значение (метод entry.getValue()). Таким образом, получаем 4 перехода. |
||
440 | |||
441 | 1 | Александр Александров | h3. Сколько создается новых объектов, когда вы добавляете новый элемент в HashMap? |
442 | |||
443 | 3 | Александр Александров | Один новый объект статического вложенного класса Entry<K,V>. |
444 | 1 | Александр Александров | |
445 | h3. Как работает HashMap при попытке сохранить в нее два элемента по ключам с одинаковым hashCode, но для которых equals == false? |
||
446 | |||
447 | 3 | Александр Александров | По значению hashCode вычисляется индекс ячейки массива, в список которой будет происходить добавление элемента. Перед добавлением осуществляется проверка на наличие уже элементов в этой ячейке. Если |
448 | элементов нет, то происходит добавление. Если возникает коллизия, то итеративно осуществляется обход списка в поисках элемента с таким же ключом и хэш-кодом. Если такой элемент найден, то его значение перезаписывается, а старое - возвращается. Поскольку в условии сказано, что добавляемые ключи - разные, то второй элемент будет добавлен в начало списка. |
||
449 | 1 | Александр Александров | |
450 | h3. HashMap может выродиться в список даже для ключей с разным hashCode. Как это возможно? |
||
451 | |||
452 | 3 | Александр Александров | Это возможно в случае, если метод, определяющий номер ячейки массива по hashCode будет возвращать одинаковое значение. |
453 | 1 | Александр Александров | |
454 | h3. Какое худшее время работы метода get(key) для ключа, которого нет в таблице (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
455 | |||
456 | 3 | Александр Александров | O(N). Худший случай - это поиск ключа в таблице, вырожденной в список, перебор ключей которой занимает линейно пропорциональное время количеству хранимых элементов. |
457 | 1 | Александр Александров | |
458 | h3. Какое худшее время работы метода get(key) для ключа, который есть в таблице (O(1), O(log(N)), O(N), O(N*log(N)), O(N*N))? |
||
459 | |||
460 | 3 | Александр Александров | O(N). Аналогичные рассуждения, что и для предыдущего вопроса. |
461 | 1 | Александр Александров | |
462 | h3. Объясните смысл параметров в конструкторе HashMap(int initialCapacity, float loadFactor). |
||
463 | |||
464 | 3 | Александр Александров | *int initialCapacity* - исходный размер HashMap (количество корзин в хэштаблице в момент её создания), по умолчанию имеет значение 16. |
465 | 1 | Александр Александров | |
466 | 3 | Александр Александров | *float loadFactor* - коэффициент заполнения HashMap. Равен отношению числа хранимых элементов в таблице к её размеру. loadFactor - является мерой заполнения таблицы элементами, при превышении количества хранимых таблицей значений , происходит автоматическое перехеширование. Значение по умолчанию 0.75 является хорошим компромиссом между временем доступа и объемом хранимых данных. |
467 | |||
468 | 1 | Александр Александров | h3. В чем разница между HashMap и IdentityHashMap? Для чего нужна IdentityHashMap? Как может быть полезна для реализации сериализации или клонирования? |
469 | 3 | Александр Александров | |
470 | 1 | Александр Александров | |
471 | |||
472 | h3. В чем разница между HashMap и WeakHashMap? Для чего нужна WeakHashMap? |
||
473 | |||
474 | |||
475 | h3. В WeakHashMap используются WeakReferences. А почему бы не создать SoftHashMap на SoftReferences? |
||
476 | |||
477 | |||
478 | h3. В WeakHashMap используются WeakReferences. А почему бы не создать PhantomHashMap на PhantomReferences? |
||
479 | |||
480 | |||
481 | h3. Сделайте HashSet из HashMap (используйте только множество ключей, но не множество значений). |
||
482 | |||
483 | |||
484 | h3. Сделайте HashMap из HashSet (HashSet<Map.Entry<K, V>>) |
||
485 | |||
486 | |||
487 | h3. Сравните интерфейсы java.util.Queue и java.util.Deque. |
||
488 | |||
489 | |||
490 | h3. Кто кого расширяет: Queue расширяет Deque, или Deque расширяет Queue? |
||
491 | |||
492 | |||
493 | h3. Почему LinkedList реализует и List, и Deque? |
||
494 | |||
495 | |||
496 | h3. В чем разница между классами java.util.Arrays и java.lang.reflect.Array? |
||
497 | |||
498 | |||
499 | h3. В чем разница между классами java.util.Collection и java.util.Collections? |
||
500 | |||
501 | |||
502 | h3. Напишите НЕмногопоточную программу, которая заставляет коллекцию выбросить ConcurrentModificationException. |
||
503 | |||
504 | |||
505 | h3. Что такое "fail-fast поведение"? |
||
506 | |||
507 | |||
508 | h3. Для множеств еnum-ов есть специальный класс java.util.EnumSet? Зачем? Чем авторов не устраивал HashSet или TreeSet? |
||
509 | |||
510 | |||
511 | h3. java.util.Stack - считается "устаревшим". Чем его рекомендуют заменять? Почему? |
||
512 | |||
513 | |||
514 | h3. Какая коллекция реализует дисциплину обслуживания FIFO? |
||
515 | |||
516 | |||
517 | h3. Какая коллекция реализует дисциплину обслуживания FILO? |
||
518 | |||
519 | |||
520 | h3. Приведите пример, когда какая-либо коллекция выбрасывает UnsupportedOperationException. |
||
521 | |||
522 | |||
523 | h3. Почему нельзя написать "ArrayList<List> numbers = new ArrayList<ArrayList>();" но можно "List<ArrayList> numbers = new ArrayList<ArrayList>();"? |
||
524 | |||
525 | |||
526 | h3. LinkedHashMap - что это еще за "зверь"? Что в нем от LinkedList, а что от HashMap? |
||
527 | |||
528 | |||
529 | h3. LinkedHashSet - что это еще за "зверь"? Что в нем от LinkedList, а что от HashSet? |
||
530 | |||
531 | |||
532 | h3. Говорят, на LinkedHashMap легко сделать простенький кэш c "invalidation policy", знаете как? |
||
533 | |||
534 | |||
535 | h3. Что позволяет сделать PriorityQueue? |
||
536 | |||
537 | |||
538 | h3. В чем заключаются отличия java.util.Comparator от java.lang.Comparable? |