Arrays.setAll fills every position in an array by calling a supplied function with that position's index and storing the returned value. The index can drive computation or be deliberately ignored. section 2.13 section 3.5
A method reference can select the wrong constructor
StringBuilder[] array = new StringBuilder[size]; Arrays.setAll(array, StringBuilder::new); This looks like a request for an empty StringBuilder at each position. However, the function receives the index, and overload resolution can select StringBuilder(int). The result is equivalent to index -> new StringBuilder(index), so later elements preallocate increasingly large buffers. Large arrays can become extremely slow or fail with OutOfMemoryError. Ignore the index explicitly when no initial capacity is intended: Arrays.setAll(array, index -> new StringBuilder()); section 2.13
Avoid common indexing and method-reference mistakes by applying these checks:
- Use a lambda when a constructor or method reference has overloads or variable-arity parameters; make ignored arguments visible. section 2.13
- Use the lambda index when each output depends on its corresponding input position, such as mapping types[i] into parameterTypes[i]. section 3.5
- Treat constant-index diagnostics inside loops as review prompts rather than proof of an error; rewrite with Arrays.setAll or Stream API when appropriate. section 3.5
Figure 2.9 Final memory layout after invoking Arrays.setAll() for size = 100. The internal byte[] buffer held by StringBuilder becomes larger and larger toward the end of the array.
Inspect how the mistaken constructor choice makes StringBuilder's internal buffers grow toward the end of the array. section 2.13
