com.bestvike.linq.enumerable.Repeat Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of linq Show documentation
Show all versions of linq Show documentation
LINQ to Objects for Java.
The newest version!
package com.bestvike.linq.enumerable;
import com.bestvike.function.Func1;
import com.bestvike.linq.IEnumerable;
import com.bestvike.linq.debug.DebuggerDisplay;
import com.bestvike.linq.exception.ExceptionArgument;
import com.bestvike.linq.exception.ThrowHelper;
import com.bestvike.linq.util.ArrayUtils;
import com.bestvike.out;
import java.util.ArrayList;
import java.util.List;
/**
* Created by 许崇雷 on 2018-05-03.
*/
public final class Repeat {
private Repeat() {
}
public static IEnumerable repeat(TResult element, int count) {
if (count < 0)
ThrowHelper.throwArgumentOutOfRangeException(ExceptionArgument.count);
if (count == 0)
return EmptyPartition.instance();
return new RepeatIterator<>(element, count);
}
}
@DebuggerDisplay("Count = {count}")
final class RepeatIterator extends Iterator implements IPartition {
private final int count;
RepeatIterator(TResult element, int count) {
assert count > 0;
this.current = element;
this.count = count;
}
@Override
public Iterator clone() {
return new RepeatIterator<>(this.current, this.count);
}
@Override
public boolean moveNext() {
// Having a separate field for the number of sent items would be more readable.
// However, we save it into _state with a bias to minimize field size of the iterator.
int sent = this.state - 1;
// We can't have sent a negative number of items, obviously. However, if this iterator
// was illegally casted to IEnumerator without GetEnumerator being called, or if we've
// already been disposed, then `sent` will be negative.
if (sent >= 0 && sent != this.count) {
++this.state;
return true;
}
this.close();
return false;
}
@Override
public void close() {
// Don't let super.close wipe current.
this.state = -1;
}
@Override
public IEnumerable _select(Func1 selector) {
return new SelectRepeatIterator<>(this.current, this.count, selector);
}
@Override
public TResult[] _toArray(Class clazz) {
TResult[] array = ArrayUtils.newInstance(clazz, this.count);
if (this.current != null)
ArrayUtils.fill(array, this.current);
return array;
}
@Override
public Object[] _toArray() {
Object[] array = new Object[this.count];
if (this.current != null)
ArrayUtils.fill(array, this.current);
return array;
}
@Override
public List _toList() {
List list = new ArrayList<>(this.count);
for (int i = 0; i != this.count; ++i)
list.add(this.current);
return list;
}
@Override
public int _getCount(boolean onlyIfCheap) {
return this.count;
}
@Override
public IPartition _skip(int count) {
assert count > 0;
return count >= this.count
? EmptyPartition.instance()
: new RepeatIterator<>(this.current, this.count - count);
}
@Override
public IPartition _take(int count) {
assert count > 0;
return count >= this.count
? this
: new RepeatIterator<>(this.current, count);
}
@Override
public TResult _tryGetElementAt(int index, out found) {
if (Integer.compareUnsigned(index, this.count) < 0) {
found.value = true;
return this.current;
}
found.value = false;
return null;
}
@Override
public TResult _tryGetFirst(out found) {
found.value = true;
return this.current;
}
@Override
public TResult _tryGetLast(out found) {
found.value = true;
return this.current;
}
}