(#) Broken Iterator
!!! WARNING: Broken Iterator
This is a warning.
Id
: `BrokenIterator`
Summary
: Broken Iterator
Severity
: Warning
Category
: Correctness
Platform
: Android
Vendor
: Android Open Source Project
Feedback
: https://issuetracker.google.com/issues/new?component=192708
Since
: 3.6.0 (February 2020)
Affects
: Kotlin and Java files
Editing
: This check runs on the fly in the IDE editor
See
: https://developer.android.com/reference/java/util/LinkedHashMap
Implementation
: [Source Code](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/IteratorDetector.kt)
Tests
: [Source Code](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/IteratorDetectorTest.kt)
**For LinkedHashMap:**
The spliterators returned by `LinkedHashMap` in Android Nougat (API
levels 24 and 25) use the wrong order (inconsistent with the iterators,
which use the correct order), despite reporting `Spliterator.ORDERED`.
You may use the following code fragments to obtain a correctly ordered
`Spliterator` on API level 24 and 25:
For a Collection view `c = lhm.entrySet()`, `c = lhm.keySet()` or `c =
lhm.values()`, use `java.util.Spliterators.spliterator(c,
c.spliterator().characteristics())` instead of `c.spliterator()`.
Instead of `c.stream()` or `c.parallelStream()`, use
`java.util.stream.StreamSupport.stream(spliterator, false)` to construct
a (nonparallel) Stream from such a `Spliterator`.
**For Vector:**
The `listIterator()` returned for a `Vector` has a broken `add()`
implementation on Android N (API level 24). Consider switching to
`ArrayList` and if necessary adding synchronization.
(##) Example
Here is an example of lint warnings produced by this check:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text
src/test/pkg/LinkedHashmapTest.java:34:Warning:
LinkedHashMap#spliterator was broken in API 24 and 25. Workaround: Use
java.util.Spliterators.spliterator(c2a,
c2a.spliterator().characteristics()) [BrokenIterator]
Spliterator<String> keys2a = c2a.spliterator(); // Warn
-----------------
src/test/pkg/LinkedHashmapTest.java:35:Warning:
LinkedHashMap#spliterator was broken in API 24 and 25. Workaround: Use
java.util.Spliterators.spliterator(c2b,
c2b.spliterator().characteristics()) [BrokenIterator]
Spliterator<String> keys2b = c2b.spliterator(); // Warn
-----------------
src/test/pkg/LinkedHashmapTest.java:36:Warning:
LinkedHashMap#spliterator was broken in API 24 and 25. Workaround: Use
java.util.Spliterators.spliterator(c2c,
c2c.spliterator().characteristics()) [BrokenIterator]
Spliterator<Entry<String, String>> keys2c = c2c.spliterator(); // Warn
-----------------
src/test/pkg/LinkedHashmapTest.java:39:Warning: LinkedHashMap#stream was
broken in API 24 and 25. Workaround: Use
java.util.stream.StreamSupport.stream(spliterator, false)
[BrokenIterator]
Stream<String> stream1 = c2a.stream(); // Warn
------------
src/test/pkg/LinkedHashmapTest.java:40:Warning:
LinkedHashMap#spliterator was broken in API 24 and 25. Workaround: Use
java.util.Spliterators.spliterator(c2a,
c2a.spliterator().characteristics()) [BrokenIterator]
StreamSupport.stream(c2a.spliterator(), false); // Warn
-----------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here are the relevant source files:
`src/test/pkg/LinkedHashmapTest.java`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers
package test.pkg;
import android.os.Build;
import androidx.annotation.RequiresApi;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class LinkedHashmapTest {
@RequiresApi(api = Build.VERSION_CODES.N)
public void test() {
Map