Skip to content

Commit

Permalink
Micro-optimize the memory usage of singletonIterator.
Browse files Browse the repository at this point in the history
- Before: 24 bytes
- After: 16 bytes

I noticed this while debugging a problem with cl/590212390. Naturally, it's not a big deal.

But hey, named classes are nicer than "`Iterators$10`."

RELNOTES=n/a
PiperOrigin-RevId: 591014189
  • Loading branch information
cpovirk authored and Google Java Core Libraries committed Dec 14, 2023
1 parent 5141cb1 commit fdd6ead
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 30 deletions.
42 changes: 27 additions & 15 deletions android/guava/src/com/google/common/collect/Iterators.java
Original file line number Diff line number Diff line change
Expand Up @@ -1106,24 +1106,36 @@ protected T get(int index) {
*/
public static <T extends @Nullable Object> UnmodifiableIterator<T> singletonIterator(
@ParametricNullness T value) {
return new UnmodifiableIterator<T>() {
boolean done;
return new SingletonIterator<>(value);
}

@Override
public boolean hasNext() {
return !done;
}
private static final class SingletonIterator<T extends @Nullable Object>
extends UnmodifiableIterator<T> {
private static final Object SENTINEL = new Object();

@Override
@ParametricNullness
public T next() {
if (done) {
throw new NoSuchElementException();
}
done = true;
return value;
private Object valueOrSentinel;

SingletonIterator(T value) {
this.valueOrSentinel = value;
}

@Override
public boolean hasNext() {
return valueOrSentinel != SENTINEL;
}

@Override
@ParametricNullness
public T next() {
if (valueOrSentinel == SENTINEL) {
throw new NoSuchElementException();
}
};
// The field held either a T or SENTINEL, and it turned out not to be SENTINEL.
@SuppressWarnings("unchecked")
T t = (T) valueOrSentinel;
valueOrSentinel = SENTINEL;
return t;
}
}

/**
Expand Down
42 changes: 27 additions & 15 deletions guava/src/com/google/common/collect/Iterators.java
Original file line number Diff line number Diff line change
Expand Up @@ -1106,24 +1106,36 @@ protected T get(int index) {
*/
public static <T extends @Nullable Object> UnmodifiableIterator<T> singletonIterator(
@ParametricNullness T value) {
return new UnmodifiableIterator<T>() {
boolean done;
return new SingletonIterator<>(value);
}

@Override
public boolean hasNext() {
return !done;
}
private static final class SingletonIterator<T extends @Nullable Object>
extends UnmodifiableIterator<T> {
private static final Object SENTINEL = new Object();

@Override
@ParametricNullness
public T next() {
if (done) {
throw new NoSuchElementException();
}
done = true;
return value;
private Object valueOrSentinel;

SingletonIterator(T value) {
this.valueOrSentinel = value;
}

@Override
public boolean hasNext() {
return valueOrSentinel != SENTINEL;
}

@Override
@ParametricNullness
public T next() {
if (valueOrSentinel == SENTINEL) {
throw new NoSuchElementException();
}
};
// The field held either a T or SENTINEL, and it turned out not to be SENTINEL.
@SuppressWarnings("unchecked")
T t = (T) valueOrSentinel;
valueOrSentinel = SENTINEL;
return t;
}
}

/**
Expand Down

0 comments on commit fdd6ead

Please sign in to comment.