[{"data":1,"prerenderedAt":175},["ShallowReactive",2],{"qa-\u002Fjava\u002Fcollections\u002Flist-map-set":3},{"page":4,"siblings":170,"blog":172},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":161,"seo":162,"seoDescription":163,"stem":164,"subtopic":165,"topic":166,"topicSlug":167,"updated":168,"__hash__":169},"qa\u002Fjava\u002Fcollections\u002Flist-map-set.md","List Map Set",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Java","java",{},true,1,"\u002Fjava\u002Fcollections\u002Flist-map-set",[23,28,32,36,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157],{"id":24,"difficulty":25,"q":26,"a":27},"collection-hierarchy","easy","What is the Java Collections Framework?","A unified set of interfaces and implementations for storing groups of objects.\nThe root is `Iterable` -> `Collection`, which branches into:\n\n- **`List`** — ordered, indexed, allows duplicates (`ArrayList`, `LinkedList`).\n- **`Set`** — no duplicates (`HashSet`, `TreeSet`, `LinkedHashSet`).\n- **`Queue`\u002F`Deque`** — ordering for processing (`ArrayDeque`, `PriorityQueue`).\n\n**`Map`** is part of the framework but **not** a `Collection` (it stores\nkey->value pairs, not single elements).\n\n```java\nList\u003CString> list = new ArrayList\u003C>();\nSet\u003CString> set   = new HashSet\u003C>();\nMap\u003CString, Integer> map = new HashMap\u003C>();\n```\n\nProgramming to the interface (`List` not `ArrayList`) lets you swap\nimplementations freely.\n",{"id":29,"difficulty":25,"q":30,"a":31},"list-vs-set-vs-map","What is the difference between List, Set and Map?","- **`List`** — an **ordered, indexed** sequence that **allows duplicates**.\n  Access by position.\n- **`Set`** — an **unordered** collection of **unique** elements (uniqueness\n  defined by `equals`\u002F`hashCode`).\n- **`Map`** — **key->value** pairs with **unique keys**; not a `Collection`.\n\n```java\nList.of(\"a\", \"a\", \"b\");          \u002F\u002F [a, a, b] — duplicates kept\nSet.of(\"a\", \"a\", \"b\");           \u002F\u002F throws — duplicate in Set.of\nnew HashSet\u003C>(List.of(\"a\",\"a\")); \u002F\u002F {a} — duplicate dropped\nMap.of(\"k1\", 1, \"k2\", 2);        \u002F\u002F {k1=1, k2=2}\n```\n\nPick by need: ordered\u002Findexed -> List; uniqueness\u002Fmembership -> Set; lookups by\nkey -> Map.\n",{"id":33,"difficulty":14,"q":34,"a":35},"arraylist-vs-linkedlist","What is the difference between ArrayList and LinkedList?","- **`ArrayList`** — backed by a **resizable array**. O(1) random access by\n  index; O(1) amortized append; O(n) insert\u002Fremove in the middle (shifting).\n  Cache-friendly, lower memory overhead.\n- **`LinkedList`** — a **doubly-linked list**. O(1) insert\u002Fremove at the ends\n  (or at a known node); but O(n) index access (must walk the chain) and higher\n  per-element memory (node pointers).\n\n```java\nList\u003CInteger> a = new ArrayList\u003C>();\na.get(1000);          \u002F\u002F O(1)\nList\u003CInteger> l = new LinkedList\u003C>();\nl.get(1000);          \u002F\u002F O(n) — walks 1000 nodes\n```\n\nIn practice **`ArrayList` wins almost always** — its cache locality beats\n`LinkedList` even for many insert\u002Fremove patterns. Use `LinkedList` mainly as a\n`Deque`\u002Fqueue.\n",{"id":37,"difficulty":38,"q":39,"a":40},"hashmap-internals","hard","How does HashMap work internally?","A `HashMap` is an **array of buckets**. To store a key it computes\n`hashCode()`, spreads the bits, and maps it to a bucket index. Collisions (keys\nlanding in the same bucket) are chained in a **linked list**, which **converts\nto a balanced tree (red-black)** once a bucket exceeds 8 entries (and the table\nis ≥64) — keeping worst-case lookups at O(log n) instead of O(n).\n\n```java\nMap\u003CString, Integer> m = new HashMap\u003C>();\nm.put(\"a\", 1);   \u002F\u002F hash(\"a\") -> bucket -> store entry\nm.get(\"a\");      \u002F\u002F hash(\"a\") -> bucket -> equals() scan -> 1\n```\n\nLookup\u002Finsert are **O(1) average**. When the size exceeds `capacity *\nloadFactor` (default 16 * 0.75 = 12), the table **resizes** (doubles) and\nrehashes. This is why a correct `hashCode`\u002F`equals` pair is essential.\n",{"id":42,"difficulty":38,"q":43,"a":44},"load-factor","What are capacity and load factor in a HashMap?","- **Capacity** — the number of buckets (always a power of two, default 16).\n- **Load factor** — the fullness threshold (default 0.75). When\n  `size > capacity * loadFactor`, the map **resizes** (capacity doubles) and\n  rehashes all entries.\n\n```java\n\u002F\u002F pre-size when you know roughly how many entries to avoid resizes\nMap\u003CString,Integer> m = new HashMap\u003C>(64);\n```\n\nThe 0.75 default trades space vs time: lower load factor = fewer collisions but\nmore memory; higher = denser but slower lookups. Pre-sizing a known-large map\navoids repeated O(n) resizes during population.\n",{"id":46,"difficulty":14,"q":47,"a":48},"hashmap-vs-hashtable","What is the difference between HashMap, Hashtable and ConcurrentHashMap?","- **`HashMap`** — not synchronized, allows **one `null` key** and `null`\n  values, fastest. Use single-threaded or with external synchronization.\n- **`Hashtable`** — legacy, **fully synchronized** (every method locks the whole\n  table), **no `null`** keys\u002Fvalues. Largely obsolete.\n- **`ConcurrentHashMap`** — thread-safe with **fine-grained locking** (per-bin\n  CAS, not a global lock), no `null` keys\u002Fvalues, high concurrency.\n\n```java\nMap\u003CString,Integer> safe = new ConcurrentHashMap\u003C>(); \u002F\u002F modern thread-safe choice\n```\n\nFor concurrent code, prefer **`ConcurrentHashMap`** over `Hashtable` or\n`Collections.synchronizedMap` — it scales far better under contention.\n",{"id":50,"difficulty":14,"q":51,"a":52},"hashset-treeset-linkedhashset","What is the difference between HashSet, LinkedHashSet and TreeSet?","- **`HashSet`** — backed by a `HashMap`; **no ordering**, O(1) add\u002Fcontains.\n- **`LinkedHashSet`** — `HashSet` + a linked list, so it preserves\n  **insertion order**; O(1) with slightly more memory.\n- **`TreeSet`** — a red-black tree; keeps elements in **sorted order**, O(log n)\n  operations, requires `Comparable`\u002F`Comparator`.\n\n```java\nnew HashSet\u003C>(List.of(3,1,2));       \u002F\u002F order undefined, e.g. [1,2,3] or other\nnew LinkedHashSet\u003C>(List.of(3,1,2)); \u002F\u002F [3, 1, 2] — insertion order\nnew TreeSet\u003C>(List.of(3,1,2));       \u002F\u002F [1, 2, 3] — sorted\n```\n\nChoose by requirement: speed -> HashSet; remember order -> LinkedHashSet; sorted\u002F\nrange queries -> TreeSet.\n",{"id":54,"difficulty":14,"q":55,"a":56},"hashmap-treemap-linkedhashmap","How do HashMap, LinkedHashMap and TreeMap differ?","They mirror the Set variants:\n\n- **`HashMap`** — no order, O(1) average.\n- **`LinkedHashMap`** — insertion order (or access order, enabling easy LRU\n  caches), O(1).\n- **`TreeMap`** — keys sorted, O(log n), supports range\u002Fnavigation methods\n  (`firstKey`, `ceilingKey`, `subMap`).\n\n```java\n\u002F\u002F LinkedHashMap as an LRU cache\nvar lru = new LinkedHashMap\u003CString,Integer>(16, 0.75f, true) {\n  protected boolean removeEldestEntry(Map.Entry\u003CString,Integer> e) {\n    return size() > 100;\n  }\n};\n```\n\n`TreeMap`'s navigation API is its superpower; `LinkedHashMap`'s access-order\nmode is the classic LRU trick.\n",{"id":58,"difficulty":38,"q":59,"a":60},"fail-fast","What is a fail-fast iterator and ConcurrentModificationException?","Most collection iterators are **fail-fast**: they track a `modCount`, and if the\ncollection is structurally modified during iteration (other than through the\niterator's own `remove`), they throw **`ConcurrentModificationException`** —\nfailing immediately rather than risking corrupt results.\n\n```java\nfor (String s : list) {\n  if (s.isEmpty()) list.remove(s); \u002F\u002F ConcurrentModificationException\n}\n\nIterator\u003CString> it = list.iterator();\nwhile (it.hasNext()) {\n  if (it.next().isEmpty()) it.remove(); \u002F\u002F safe via the iterator\n}\nlist.removeIf(String::isEmpty);          \u002F\u002F cleanest\n```\n\nFail-fast is **best-effort** (not guaranteed). Concurrent collections like\n`CopyOnWriteArrayList`\u002F`ConcurrentHashMap` are **fail-safe** instead — they\niterate over a snapshot and don't throw.\n",{"id":62,"difficulty":14,"q":63,"a":64},"comparable-vs-comparator","What is the difference between Comparable and Comparator?","- **`Comparable\u003CT>`** — the type's **natural ordering**, implemented *by the\n  class itself* via `compareTo`. One ordering per class.\n- **`Comparator\u003CT>`** — an **external** ordering object via `compare`, so you can\n  define many orderings without touching the class.\n\n```java\nclass User implements Comparable\u003CUser> {\n  int age; String name;\n  public int compareTo(User o) { return Integer.compare(age, o.age); } \u002F\u002F natural\n}\n\u002F\u002F alternate orderings without modifying User:\nusers.sort(Comparator.comparing(u -> u.name));\nusers.sort(Comparator.comparingInt((User u) -> u.age).reversed()\n                     .thenComparing(u -> u.name));\n```\n\nRule of thumb: one obvious default ordering -> `Comparable`; multiple\u002Fcontextual\norderings -> `Comparator` (which also composes nicely with `thenComparing`).\n",{"id":66,"difficulty":14,"q":67,"a":68},"iterator-vs-listiterator","What is the difference between Iterator and ListIterator?","- **`Iterator`** — forward-only traversal of any `Collection`; supports\n  `hasNext`, `next`, and `remove`.\n- **`ListIterator`** — a `List`-only iterator that goes **both directions**\n  (`hasPrevious`\u002F`previous`), exposes indices (`nextIndex`), and can **`add`**\n  and **`set`** elements during iteration.\n\n```java\nListIterator\u003CString> it = list.listIterator();\nwhile (it.hasNext()) {\n  String s = it.next();\n  if (s.isBlank()) it.set(\"(empty)\"); \u002F\u002F replace in place\n}\n```\n\nUse `ListIterator` when you need to walk backward or modify elements while\niterating a list.\n",{"id":70,"difficulty":14,"q":71,"a":72},"arraylist-resize","How does ArrayList grow, and what is amortized O(1)?","An `ArrayList` holds an internal array. When it fills up, it allocates a **larger\narray** (~1.5×) and copies the elements over — an O(n) operation. But because\ngrowth happens **rarely** (geometrically), the *average* cost of `add` over many\ncalls is **O(1) amortized**.\n\n```java\nList\u003CInteger> list = new ArrayList\u003C>(1000); \u002F\u002F pre-size: skip the resizes\nfor (int i = 0; i \u003C 1000; i++) list.add(i);\n```\n\nIf you know the final size, pass an **initial capacity** to avoid the repeated\ncopies. Note `size()` (number of elements) differs from the internal capacity.\n",{"id":74,"difficulty":25,"q":75,"a":76},"generics-why","Why are generics used in collections?","Generics give collections **compile-time type safety** and remove casts. Before\ngenerics, collections held `Object`, so you could insert anything and had to cast\non the way out — risking `ClassCastException` at runtime.\n\n```java\nList\u003CString> names = new ArrayList\u003C>();\nnames.add(\"Ada\");\nString s = names.get(0);   \u002F\u002F no cast; adding an Integer won't compile\n\nList raw = new ArrayList(); \u002F\u002F raw type — unsafe, avoid\nraw.add(42);\nString bad = (String) raw.get(0); \u002F\u002F compiles, ClassCastException at runtime\n```\n\nGenerics catch type errors at **compile time** and make code self-documenting.\n",{"id":78,"difficulty":38,"q":79,"a":80},"type-erasure","What is type erasure?","Java generics are a **compile-time** feature. After type checking, the compiler\n**erases** type parameters — `List\u003CString>` and `List\u003CInteger>` both become raw\n`List` at runtime, with casts inserted automatically. This keeps backward\ncompatibility with pre-generics code.\n\n```java\nList\u003CString> a = new ArrayList\u003C>();\nList\u003CInteger> b = new ArrayList\u003C>();\na.getClass() == b.getClass();  \u002F\u002F true — same runtime class\n\n\u002F\u002F consequences of erasure:\n\u002F\u002F new T[]      -> illegal\n\u002F\u002F x instanceof List\u003CString> -> illegal (only List\u003C?>)\n```\n\nErasure is why you can't do `new T()`, create generic arrays, or check a generic\ntype with `instanceof` — the type info simply isn't there at runtime.\n",{"id":82,"difficulty":38,"q":83,"a":84},"wildcards","What do the ? extends and ? super wildcards mean (PECS)?","Bounded wildcards control what you can read\u002Fwrite through a generic reference:\n\n- **`? extends T`** — an unknown subtype of T; you can **read** Ts out, but\n  **can't add** (the exact type is unknown). A **Producer**.\n- **`? super T`** — an unknown supertype of T; you can **add** Ts, but reads come\n  back as `Object`. A **Consumer**.\n\nThe mnemonic is **PECS — Producer `extends`, Consumer `super`**:\n\n```java\nvoid copy(List\u003C? extends Number> src, List\u003C? super Number> dst) {\n  for (Number n : src) dst.add(n); \u002F\u002F read from producer, write to consumer\n}\n```\n\n`src` produces values (read-only), `dst` consumes them (write-ok). This is how\n`Collections.copy` and friends are typed.\n",{"id":86,"difficulty":14,"q":87,"a":88},"queue-deque","What are Queue and Deque, and which implementations are common?","- **`Queue`** — FIFO processing; `offer`\u002F`poll`\u002F`peek`. `PriorityQueue` orders\n  by priority instead of arrival.\n- **`Deque`** (\"deck\") — double-ended queue; add\u002Fremove at **both ends**. Works\n  as a queue **or** a stack.\n\n```java\nDeque\u003CInteger> stack = new ArrayDeque\u003C>();\nstack.push(1); stack.push(2); stack.pop();  \u002F\u002F LIFO -> 2\n\nQueue\u003CInteger> q = new ArrayDeque\u003C>();\nq.offer(1); q.offer(2); q.poll();           \u002F\u002F FIFO -> 1\n\nQueue\u003CInteger> pq = new PriorityQueue\u003C>();\npq.offer(5); pq.offer(1); pq.peek();        \u002F\u002F 1 (smallest first)\n```\n\nPrefer **`ArrayDeque`** over the legacy `Stack` class (synchronized, extends\n`Vector`) for stack\u002Fqueue needs.\n",{"id":90,"difficulty":14,"q":91,"a":92},"immutable-collections","How do you create immutable collections?","- **`List.of` \u002F `Set.of` \u002F `Map.of`** (Java 9+) — concise, truly immutable,\n  reject `null` and (for Set\u002FMap) duplicates.\n- **`Collections.unmodifiableList(...)`** — an unmodifiable *view* over an\n  existing collection.\n- **`List.copyOf(...)`** — an immutable copy of any collection.\n\n```java\nList\u003CString> a = List.of(\"x\", \"y\");        \u002F\u002F immutable\na.add(\"z\");                                 \u002F\u002F UnsupportedOperationException\n\nList\u003CString> backing = new ArrayList\u003C>(List.of(\"x\"));\nList\u003CString> view = Collections.unmodifiableList(backing);\nbacking.add(\"y\");                           \u002F\u002F view reflects this — it's a VIEW\n```\n\nGotcha: `unmodifiableList` is a **view** — mutating the backing list still shows\nthrough it. `List.of`\u002F`copyOf` are genuinely independent and immutable.\n",{"id":94,"difficulty":14,"q":95,"a":96},"null-handling","Which collections allow null and which do not?","- **`HashMap`** — one `null` key, many `null` values. **`HashSet`** — one\n  `null` element. `ArrayList`\u002F`LinkedList` allow `null`s.\n- **`Hashtable`, `ConcurrentHashMap`, `TreeMap` (keys)** — **no `null`** (TreeMap\n  can't compare null; concurrent maps disallow it to avoid ambiguity).\n- **`List.of`\u002F`Set.of`\u002F`Map.of`** — reject `null` entirely.\n\n```java\nnew HashMap\u003C>().put(null, 1);          \u002F\u002F\nnew ConcurrentHashMap\u003C>().put(null,1); \u002F\u002F NullPointerException\nList.of(\"a\", null);                    \u002F\u002F NullPointerException\n```\n\nAvoiding `null` (using `Optional` or sentinel objects) sidesteps a whole class\nof these errors.\n",{"id":98,"difficulty":25,"q":99,"a":100},"collections-utility","What does the Collections utility class provide?","`java.util.Collections` is a toolbox of static helpers that operate on\ncollections: `sort`, `reverse`, `shuffle`, `min`\u002F`max`, `binarySearch`,\n`frequency`, `unmodifiableXxx`, `synchronizedXxx`, and `emptyList()`\u002F\n`singletonList()`.\n\n```java\nList\u003CInteger> nums = new ArrayList\u003C>(List.of(3, 1, 2));\nCollections.sort(nums);                 \u002F\u002F [1, 2, 3]\nCollections.reverse(nums);              \u002F\u002F [3, 2, 1]\nint max = Collections.max(nums);        \u002F\u002F 3\n```\n\nDon't confuse `Collections` (utility class, plural) with `Collection` (the\ninterface). `Arrays` is its array-focused sibling (`Arrays.sort`,\n`Arrays.asList`).\n",{"id":102,"difficulty":38,"q":103,"a":104},"arrays-aslist","What are the pitfalls of Arrays.asList()?","`Arrays.asList` returns a **fixed-size list backed by the array** — not a normal\n`ArrayList`. You can `set` elements (it writes through to the array) but **can't\n`add`\u002F`remove`** (throws `UnsupportedOperationException`).\n\n```java\nList\u003CInteger> l = Arrays.asList(1, 2, 3);\nl.set(0, 9);   \u002F\u002F writes through to the backing array\nl.add(4);      \u002F\u002F UnsupportedOperationException\n\n\u002F\u002F also: a primitive array gives a 1-element List\u003Cint[]>, not List\u003CInteger>!\nList\u003Cint[]> oops = Arrays.asList(new int[]{1, 2, 3}); \u002F\u002F size 1\n\nList\u003CInteger> real = new ArrayList\u003C>(Arrays.asList(1, 2, 3)); \u002F\u002F mutable copy\n```\n\nWrap it in `new ArrayList\u003C>(...)` for a fully mutable list, and remember\nautoboxing: pass `Integer[]`, not `int[]`.\n",{"id":106,"difficulty":14,"q":107,"a":108},"set-uniqueness","How does a HashSet decide that two elements are duplicates?","A `HashSet` (backed by a `HashMap`) treats two elements as duplicates when their\n**`hashCode()` matches** *and* **`equals()` returns true**. So uniqueness depends\nentirely on a correct `equals`\u002F`hashCode` implementation.\n\n```java\nclass P { int x;\n  \u002F\u002F no equals\u002FhashCode -> identity-based, \"duplicates\" stay\n}\nSet\u003CP> s = new HashSet\u003C>();\ns.add(new P()); s.add(new P());  \u002F\u002F size 2 (different objects)\n```\n\nIf you forget to override them, two logically-equal objects are treated as\ndistinct. If you override `equals` but not `hashCode` (or vice versa), the set\nmay store duplicates or fail to find elements.\n",{"id":110,"difficulty":38,"q":111,"a":112},"mutable-key","What happens if you use a mutable object as a HashMap key?","The map places the key in a bucket based on its **hash at insertion time**. If\nyou then **mutate the key** so its `hashCode` changes, it ends up in the \"wrong\"\nbucket — the map can no longer find it, even with the same reference.\n\n```java\nMap\u003CList\u003CInteger>, String> m = new HashMap\u003C>();\nList\u003CInteger> key = new ArrayList\u003C>(List.of(1));\nm.put(key, \"v\");\nkey.add(2);                 \u002F\u002F mutates the key -> hashCode changes\nm.get(key);                 \u002F\u002F null! lost in the wrong bucket\n```\n\nRule: **use immutable keys** (`String`, `Integer`, records, frozen value\nobjects). It's the same reason Python forbids list keys.\n",{"id":114,"difficulty":14,"q":115,"a":116},"concurrent-modification-map","How do you safely remove entries from a Map while iterating?","Don't call `map.remove` inside an enhanced-for over its entries — that throws\n`ConcurrentModificationException`. Use the **iterator's `remove`**, or the\ncleaner `removeIf`\u002F`entrySet().removeIf`, or `keySet`\u002F`values` views.\n\n```java\n\u002F\u002F iterator\nIterator\u003CMap.Entry\u003CString,Integer>> it = map.entrySet().iterator();\nwhile (it.hasNext()) {\n  if (it.next().getValue() == 0) it.remove();\n}\n\u002F\u002F concise\nmap.values().removeIf(v -> v == 0);\nmap.entrySet().removeIf(e -> e.getValue() == 0);\n```\n\nFor concurrent access from multiple threads, use `ConcurrentHashMap`, whose\niterators are fail-safe.\n",{"id":118,"difficulty":14,"q":119,"a":120},"stack-vector","Why are Vector and Stack discouraged?","`Vector` and its subclass `Stack` are **legacy synchronized** collections from\nJava 1.0. Every method is synchronized, so they pay locking overhead even in\nsingle-threaded code, and that per-method locking doesn't make *compound*\noperations atomic anyway.\n\n```java\nDeque\u003CInteger> stack = new ArrayDeque\u003C>(); \u002F\u002F modern stack\nList\u003CInteger> list = new ArrayList\u003C>();    \u002F\u002F modern list\n```\n\nUse `ArrayList` (unsynchronized list), `ArrayDeque` (stack\u002Fqueue), and pick a\n*concurrent* collection or explicit synchronization when you genuinely need\nthread safety — not `Vector`\u002F`Stack`.\n",{"id":122,"difficulty":14,"q":123,"a":124},"map-getordefault-merge","What do getOrDefault, computeIfAbsent and merge do?","Java 8 added convenience methods that simplify common map idioms:\n\n- **`getOrDefault(k, d)`** — value for `k`, or `d` if absent.\n- **`computeIfAbsent(k, fn)`** — compute and store a value only if `k` is\n  missing; perfect for multimaps.\n- **`merge(k, v, fn)`** — combine an existing value with a new one; perfect for\n  counting.\n\n```java\n\u002F\u002F grouping (multimap)\nmap.computeIfAbsent(key, k -> new ArrayList\u003C>()).add(item);\n\n\u002F\u002F frequency count\ncounts.merge(word, 1, Integer::sum);\n\nint n = counts.getOrDefault(\"x\", 0);\n```\n\nThese replace verbose `if (map.containsKey(...)) ... else ...` blocks and are\natomic on `ConcurrentHashMap`.\n",{"id":126,"difficulty":14,"q":127,"a":128},"priorityqueue","How does a PriorityQueue work?","A `PriorityQueue` is a **binary heap** that always dequeues the **highest-\npriority** element (by natural order or a `Comparator`), not FIFO. `offer`\u002F`poll`\nare O(log n); `peek` is O(1).\n\n```java\n\u002F\u002F min-heap (default): smallest first\nQueue\u003CInteger> min = new PriorityQueue\u003C>();\n\u002F\u002F max-heap: reverse the comparator\nQueue\u003CInteger> max = new PriorityQueue\u003C>(Comparator.reverseOrder());\nmax.offer(1); max.offer(5); max.peek(); \u002F\u002F 5\n```\n\nCaveat: it's only ordered at the **head** — iterating it does *not* yield sorted\norder. It's the go-to for \"top-K\", Dijkstra, and scheduling problems.\n",{"id":130,"difficulty":14,"q":131,"a":132},"synchronized-collections","What is the difference between synchronized and concurrent collections?","- **`Collections.synchronizedList\u002FMap(...)`** — wraps a collection so each method\n  locks the **whole object**. Simple, but compound operations\n  (check-then-act, iteration) still need external synchronization, and there's\n  no concurrency.\n- **Concurrent collections** (`ConcurrentHashMap`, `CopyOnWriteArrayList`,\n  `ConcurrentLinkedQueue`) — designed for concurrency with fine-grained or\n  lock-free strategies; far better throughput.\n\n```java\nList\u003CInteger> s = Collections.synchronizedList(new ArrayList\u003C>());\nsynchronized (s) {                 \u002F\u002F still must lock to iterate safely\n  for (int x : s) { }\n}\nMap\u003CString,Integer> c = new ConcurrentHashMap\u003C>(); \u002F\u002F no external lock needed\n```\n\nPrefer the concurrent collections in new code.\n",{"id":134,"difficulty":38,"q":135,"a":136},"copyonwrite","When would you use CopyOnWriteArrayList?","`CopyOnWriteArrayList` makes a fresh copy of the backing array on **every\nmutation**, so reads and iteration are **lock-free and never throw\n`ConcurrentModificationException`** (iterators see a stable snapshot). The cost:\nwrites are O(n).\n\n```java\nList\u003CListener> listeners = new CopyOnWriteArrayList\u003C>();\nfor (Listener l : listeners) l.onEvent(); \u002F\u002F safe even if another thread adds\n```\n\nIdeal for **read-mostly, write-rarely** scenarios with concurrent iteration —\nclassically event-listener lists. Terrible for write-heavy workloads.\n",{"id":138,"difficulty":14,"q":139,"a":140},"equals-in-collections","Why must equals and hashCode be consistent for collections to work?","Hash-based collections (`HashMap`, `HashSet`) locate elements by **hash first,\nthen `equals`**. If two equal objects have different hash codes, they land in\ndifferent buckets and the collection can't recognize them as the same — you get\nduplicates in a Set or failed lookups in a Map.\n\n```java\nclass Key {\n  int id;\n  Key(int id) { this.id = id; }\n  @Override public boolean equals(Object o) {\n    return o instanceof Key k && k.id == id;\n  }\n  \u002F\u002F forgot hashCode -> equal Keys get different hashes\n}\nMap\u003CKey,String> m = new HashMap\u003C>();\nm.put(new Key(1), \"a\");\nm.get(new Key(1));   \u002F\u002F null — wrong bucket\n```\n\nAlways override **both together**, keeping them based on the same fields.\n",{"id":142,"difficulty":38,"q":143,"a":144},"tree-navigation","What navigation methods do TreeMap and TreeSet provide?","Because they're sorted, `TreeMap`\u002F`TreeSet` (the `NavigableMap`\u002F`NavigableSet`\ninterfaces) offer **range and neighbor queries** that hash structures can't:\n\n- `first()\u002Flast()`, `floor(x)` (≤ x), `ceiling(x)` (≥ x), `lower(x)` (\u003C x),\n  `higher(x)` (> x).\n- `headSet`, `tailSet`, `subSet` \u002F `headMap`, `tailMap`, `subMap` for ranges.\n\n```java\nNavigableSet\u003CInteger> s = new TreeSet\u003C>(List.of(10, 20, 30));\ns.floor(25);    \u002F\u002F 20  (largest ≤ 25)\ns.ceiling(25);  \u002F\u002F 30  (smallest ≥ 25)\ns.subSet(15, 35); \u002F\u002F [20, 30]\n```\n\nThese make `TreeMap`\u002F`TreeSet` the choice for \"nearest value\", ranges, and\nordered iteration — at O(log n) per operation.\n",{"id":146,"difficulty":14,"q":147,"a":148},"enumset-enummap","What are EnumSet and EnumMap and why use them?","Specialized, highly efficient collections for **enum** keys\u002Felements.\n`EnumSet` is internally a **bit vector**; `EnumMap` is backed by a **plain\narray** indexed by `ordinal()`. Both are much faster and smaller than\n`HashSet`\u002F`HashMap` for enums, and iterate in **enum declaration order**.\n\n```java\nenum Day { MON, TUE, WED, THU, FRI, SAT, SUN }\nEnumSet\u003CDay> weekend = EnumSet.of(Day.SAT, Day.SUN);\nEnumMap\u003CDay, String> plans = new EnumMap\u003C>(Day.class);\nplans.put(Day.MON, \"gym\");\n```\n\nWhenever your keys are enum constants, prefer these over the general-purpose\ncollections.\n",{"id":150,"difficulty":14,"q":151,"a":152},"stream-collectors","How do you build collections from a Stream?","Terminal `collect` with the `Collectors` factory turns a stream into a\ncollection or grouped structure:\n\n```java\nList\u003CString> upper = names.stream()\n    .map(String::toUpperCase)\n    .collect(Collectors.toList());        \u002F\u002F or .toList() (Java 16+)\n\nMap\u003CBoolean, List\u003CInteger>> parts = nums.stream()\n    .collect(Collectors.partitioningBy(n -> n % 2 == 0));\n\nMap\u003CDept, List\u003CEmp>> byDept = emps.stream()\n    .collect(Collectors.groupingBy(Emp::dept));\n```\n\n`Collectors` covers `toSet`, `toMap`, `groupingBy`, `partitioningBy`,\n`joining`, and `counting` — declarative replacements for manual loop-and-add.\n",{"id":154,"difficulty":38,"q":155,"a":156},"list-remove-int-trap","What is the trap with List.remove and an int argument?","`List` has two overloads: `remove(int index)` removes **by position**, and\n`remove(Object o)` removes **by value**. With a `List\u003CInteger>`, passing a\nprimitive `int` calls the **index** version — not the value one.\n\n```java\nList\u003CInteger> list = new ArrayList\u003C>(List.of(10, 20, 30));\nlist.remove(1);                 \u002F\u002F removes INDEX 1 -> [10, 30]\nlist.remove(Integer.valueOf(10)); \u002F\u002F removes the VALUE 10 -> [30]\n```\n\nTo remove a value, box it explicitly with `Integer.valueOf(x)` (or cast to\n`(Integer)`). This is one of the most common surprise bugs with integer lists.\n",{"id":158,"difficulty":25,"q":159,"a":160},"choosing-collection","How do you choose the right collection for a task?","Match the data structure to the dominant operation:\n\n- Ordered list, index access, mostly appends -> **`ArrayList`**.\n- Unique elements, fast membership tests -> **`HashSet`**.\n- Key->value lookups -> **`HashMap`**.\n- Need sorted order or range queries -> **`TreeMap`\u002F`TreeSet`**.\n- Preserve insertion order -> **`LinkedHashMap`\u002F`LinkedHashSet`**.\n- FIFO queue \u002F stack -> **`ArrayDeque`**; priority -> **`PriorityQueue`**.\n- Concurrent access -> **`ConcurrentHashMap`**, `CopyOnWriteArrayList`.\n\n```java\nMap\u003CString,Integer> wordCount = new HashMap\u003C>();   \u002F\u002F counting\nSet\u003CString> seen = new HashSet\u003C>();                \u002F\u002F dedupe\n```\n\nStart from the access pattern (lookup? order? uniqueness? concurrency?) and the\nchoice usually falls out.\n",null,{"description":11},"Java Collections Framework interview questions — List vs Set vs Map, ArrayList vs LinkedList, HashMap internals, fail-fast iterators, Comparable vs Comparator, generics and immutable collections.","java\u002Fcollections\u002Flist-map-set","Lists, Maps & Sets","Collections","collections","2026-06-18","4nQd1Mi8XVoUVUsO5rEz9BXEiWRC6sSMJZ0skAAkT9g",[171],{"subtopic":165,"path":21,"order":20},{"path":173,"title":174},"\u002Fblog\u002Fjava-collections-framework-list-map-set","Java Collections Framework — Lists, Maps & Sets Explained",1781808676592]