Arrays, BitSet, and Primitives
Discover the performance foundations that power many Java collections. From the Arrays utility class with its essential methods to BitSet for memory-efficient boolean storage, understand when primitives outperform objects and how to leverage them effectively.
📋 At a Glance
| Aspect | Details |
|---|---|
| Topic | Arrays class, primitive arrays, BitSet, memory optimization |
| Complexity | Intermediate |
| Prerequisites | Part 1 (Framework Architecture) |
| Time to Master | 3-4 hours |
| Interview Frequency | High (Arrays.asList trap, primitive vs wrapper performance) |
🎯 What You'll Learn
After completing this article, you will be able to:
- Understand Arrays.asList() gotchas and fixed-size list behavior
- Choose between primitive arrays and wrapper collections for performance
- Use BitSet for memory-efficient flag storage
- Leverage parallel array operations effectively
- Avoid common boxing/unboxing performance traps
Production Story: The Fixed-Size List Disaster
The Incident
UnsupportedOperationException left and right.The error logs pointed to what seemed like innocent code:
JAVA(15 lines)CodeLoading syntax highlighter...
Why Arrays.asList() Isn't What You Think
Arrays.asList() doesn't return a regular ArrayList. It returns java.util.Arrays$ArrayList - a fixed-size list backed by the original array.JAVA(10 lines)CodeLoading syntax highlighter...
Let me show you the actual implementation:
JAVA(25 lines)CodeLoading syntax highlighter...
The Traps
JAVA(21 lines)CodeLoading syntax highlighter...
The Fix
JAVA(17 lines)CodeLoading syntax highlighter...
Impact and Lessons
- 2,847 failed recommendation requests in 15 minutes
- Users saw empty recommendation panels
- SEO impact from error responses
Arrays.asList()returns a fixed-size view, not a copy- Always wrap in
new ArrayList<>()if you need mutability - Unit tests should cover add/remove operations
- Consider
List.of()when immutability is acceptable
Mental Model: Arrays as Building Blocks
Think of arrays as the concrete foundation of a building:
TEXT(37 lines)CodeLoading syntax highlighter...
BitSet as Compact Boolean Storage
TEXT(10 lines)CodeLoading syntax highlighter...
Deep Dive: Arrays Utility Class
Arrays.asList() - The View Pattern
JAVA(15 lines)CodeLoading syntax highlighter...
Arrays.copyOf() and copyOfRange()
JAVA(14 lines)CodeLoading syntax highlighter...
Arrays.fill() and setAll()
JAVA(14 lines)CodeLoading syntax highlighter...
Arrays.sort() vs parallelSort()
JAVA(17 lines)CodeLoading syntax highlighter...
Arrays.binarySearch()
JAVA(12 lines)CodeLoading syntax highlighter...
Arrays.mismatch() and compare() (Java 9+)
JAVA(17 lines)CodeLoading syntax highlighter...
Deep Dive: Primitive Arrays vs Wrapper Collections
Memory Comparison
JAVA(20 lines)CodeLoading syntax highlighter...
Performance Comparison
JAVA(36 lines)CodeLoading syntax highlighter...
Boxing/Unboxing Traps
JAVA(29 lines)CodeLoading syntax highlighter...
When to Use What
TEXT(13 lines)CodeLoading syntax highlighter...
Deep Dive: BitSet
BitSet Basics
JAVA(19 lines)CodeLoading syntax highlighter...
BitSet Memory Efficiency
JAVA(16 lines)CodeLoading syntax highlighter...
BitSet Operations
JAVA(34 lines)CodeLoading syntax highlighter...
BitSet Iteration
JAVA(21 lines)CodeLoading syntax highlighter...
BitSet Use Cases
JAVA(51 lines)CodeLoading syntax highlighter...
Deep Dive: Parallel Array Operations
When Parallel Helps
JAVA(14 lines)CodeLoading syntax highlighter...
parallelPrefix() - Cumulative Operations
JAVA(18 lines)CodeLoading syntax highlighter...
Parallel Stream from Arrays
JAVA(18 lines)CodeLoading syntax highlighter...
⚠️ Common Mistakes
Mistake 1: Modifying Arrays.asList() Result
JAVA(11 lines)CodeLoading syntax highlighter...
Mistake 2: Arrays.asList() with Primitives
JAVA(14 lines)CodeLoading syntax highlighter...
Mistake 3: Forgetting to Sort Before binarySearch
JAVA(9 lines)CodeLoading syntax highlighter...
Mistake 4: Integer Comparison with ==
JAVA(12 lines)CodeLoading syntax highlighter...
Mistake 5: BitSet Size Confusion
JAVA(13 lines)CodeLoading syntax highlighter...
🐛 Debug This
Challenge 1: The Disappearing Elements
JAVA(10 lines)CodeLoading syntax highlighter...
X, Y, CThe list is backed by the array, so:
list.set(0, "X")changesarray[0]to "X"array[1] = "Y"changeslist.get(1)to "Y"
Both the list and array reflect all changes.
Challenge 2: The Unexpected Size
JAVA(7 lines)CodeLoading syntax highlighter...
1, 5intsis anint[](primitive array).Arrays.asList(ints)treats it as a single object, creatingList<int[]>with size 1.objectsis anObject[].Arrays.asList(objects)createsList<Object>with 5 elements.
Challenge 3: The BitSet Mystery
JAVA(11 lines)CodeLoading syntax highlighter...
Output:
TEXT(2 lines)CodeLoading syntax highlighter...
XOR sets bits that are in one set but not both:
- Bit 1: in a only → set
- Bit 2: in b only → set
- Bit 3: in both → cleared
💻 Exercises
Exercise 1: Safe ArrayList Creation
ArrayList from varargs, handling both objects and primitives:JAVA(4 lines)CodeLoading syntax highlighter...
JAVA(19 lines)CodeLoading syntax highlighter...
Exercise 2: BitSet-based Set Operations
Implement a class that uses BitSet for efficient set operations on integers in a known range:
JAVA(10 lines)CodeLoading syntax highlighter...
JAVA(49 lines)CodeLoading syntax highlighter...
Exercise 3: Parallel Array Processor
Create a utility for parallel array processing with configurable threshold:
JAVA(6 lines)CodeLoading syntax highlighter...
JAVA(33 lines)CodeLoading syntax highlighter...
Exercise 4: Array Rotation
Implement efficient in-place array rotation:
JAVA(6 lines)CodeLoading syntax highlighter...
JAVA(25 lines)CodeLoading syntax highlighter...
Exercise 5: Find Missing Numbers
Use BitSet to find missing numbers in a sequence:
JAVA(4 lines)CodeLoading syntax highlighter...
JAVA(28 lines)CodeLoading syntax highlighter...
🎤 Senior-Level Interview Questions
Question 1: Arrays.asList() Behavior
Arrays.asList() and List.of()? When would you use each?| Aspect | Arrays.asList() | List.of() (Java 9+) |
|---|---|---|
| Mutability | Fixed-size (can set, can't add/remove) | Fully immutable |
| Null elements | Allowed | Not allowed |
| Array backing | Yes (changes reflect) | No (defensive copy) |
| Memory | Shares with source array | Own memory |
JAVA(8 lines)CodeLoading syntax highlighter...
Question 2: Primitive vs Wrapper Performance
int[] significantly faster than ArrayList<Integer> for numerical operations?-
No boxing/unboxing:
int[]stores raw 4-byte values.ArrayList<Integer>requires creating Integer objects (boxing) and extracting int values (unboxing). -
Memory layout:
int[]is contiguous in memory (cache-friendly).ArrayList<Integer>stores references to Integer objects scattered in heap. -
Memory overhead:
int[]uses 4 bytes per element.Integeruses ~20 bytes per element (16-byte object header + 4-byte int + reference).
JAVA(2 lines)CodeLoading syntax highlighter...
Question 3: BitSet Internals
long[] array internally, where each long stores 64 bits:JAVA(14 lines)CodeLoading syntax highlighter...
Space comparison for 10,000 flags:
boolean[]: 10,000 bytesHashSet<Integer>(50% set): ~200,000 bytesBitSet: ~1,280 bytes (10,000/64 * 8)
BitSet is 8x better than boolean[] and ~150x better than HashSet.
Question 4: parallelSort() vs sort()
Arrays.parallelSort() instead of Arrays.sort()?parallelSort() when:- Array has more than ~8,192 elements (JDK threshold)
- Operation is CPU-bound (no I/O waiting)
- Multiple CPU cores are available
- Elements are independent (no shared state)
Don't use when:
- Small arrays (parallel overhead > benefit)
- Already in a parallel context (thread pool saturation)
- Deterministic ordering needed (parallelSort is stable but may vary)
JAVA(6 lines)CodeLoading syntax highlighter...
Question 5: Array Copy Methods
System.arraycopy(), Arrays.copyOf(), and clone()?JAVA(22 lines)CodeLoading syntax highlighter...
Question 6: Integer Cache
== comparison.-XX:AutoBoxCacheMax):JAVA(20 lines)CodeLoading syntax highlighter...
📝 Summary & Key Takeaways
Arrays.asList() Essentials
- Returns fixed-size list backed by array
- Cannot add/remove, but can set elements
- Changes bidirectionally reflect in array and list
- Doesn't work as expected with primitive arrays
Primitive vs Wrapper Performance
int[]uses 6x less memory thanArrayList<Integer>- Avoid boxing/unboxing in hot loops
- Use primitive streams (IntStream, LongStream, DoubleStream)
- Integer cache: -128 to 127 are cached, use
.equals()for comparison
BitSet Benefits
- 8x more memory-efficient than
boolean[] - Efficient set operations (and, or, xor)
- Use for flags, Bloom filters, sieves
cardinality()for count,stream()for iteration
Parallel Operations
- Use
parallelSort()for arrays > 8,192 elements parallelSetAll()for expensive computationsparallelPrefix()for cumulative operations- Not always faster - measure before using
🏁 Conclusion
Arrays and BitSet are the unsung heroes of Java collections. While ArrayList and HashMap get all the attention, understanding these foundational types helps you:
- Avoid common traps like the Arrays.asList() fixed-size gotcha
- Optimize memory using primitive arrays and BitSet where appropriate
- Improve performance with parallel array operations
- Make informed choices between primitives and wrappers
Key takeaways:
Arrays.asList()returns a view, not a copy - wrap innew ArrayList<>()for mutability- Primitive arrays are 6x more memory-efficient than wrapper collections
- BitSet is perfect for boolean flags and set operations on integers
- Parallel operations help for large arrays (>8,192 elements)
In the next article, we'll dive into ArrayList's internals - seeing how it uses these array primitives to provide a dynamic, growable collection.
📅 Review Schedule
To solidify your understanding, review this material:
- Tomorrow: Re-read the Arrays.asList() traps section
- In 3 days: Implement Exercise 2 (BitSet-based Set) again
- In 1 week: Explain primitive vs wrapper performance to a colleague
- In 2 weeks: Review the production story and common mistakes