javafixes.collection.LinkedArrayQueue Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javafixes Show documentation
Show all versions of javafixes Show documentation
Things I would like to have in Java by default
package javafixes.collection;
import java.util.*;
import static java.lang.Math.min;
// todo: mtymes - put into README.md
// todo: mtymes - test this
// todo: mtymes - add javadoc
public class LinkedArrayQueue extends AbstractQueue {
private transient Node first;
private transient Node last;
private transient int size = 0;
public LinkedArrayQueue(int arraySize) {
this.first = new Node(arraySize);
this.last = this.first;
}
public LinkedArrayQueue() {
this(128);
}
@Override
public Iterator iterator() {
return new NodeIterator();
}
// todo: pollNIterable - partition
@Override
public boolean isEmpty() {
return !first.hasNext();
}
@Override
public int size() {
return size;
}
@Override
public boolean offer(T t) {
last.add(t);
return true;
}
@Override
public T poll() {
if (first.hasNext()) {
return first.remove();
} else {
return null;
}
}
public List pollN(int n) {
List values = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (first.hasNext()) {
values.add(first.remove());
} else {
break;
}
}
return values;
}
@Override
public T peek() {
if (first.hasNext()) {
return first.peek();
} else {
return null;
}
}
private class Node {
int writeIndex = -1;
int readIndex = -1;
final Object[] values;
Node next = null;
private Node(int size) {
values = new Object[size];
}
int size() {
return min(writeIndex, values.length - 1) - min(readIndex, values.length - 1);
}
void add(T value) {
int index = ++writeIndex;
if (index >= values.length) {
if (next == null) {
next = new Node(values.length);
last = next;
}
next.add(value);
} else {
values[index] = value;
size++;
}
}
T remove() {
if (readIndex >= writeIndex) {
throw new IndexOutOfBoundsException("No additional data");
}
int index = ++readIndex;
if (index >= values.length) {
if (next != null) {
first = next;
return next.remove();
} else {
throw new IndexOutOfBoundsException("No additional data");
}
}
T value = (T) values[index];
values[index] = null;
size--;
return value;
}
T peek() {
if (readIndex >= writeIndex) {
throw new IndexOutOfBoundsException("No additional data");
}
int index = readIndex + 1;
if (index >= values.length) {
if (next != null) {
first = next;
return next.peek();
} else {
throw new IndexOutOfBoundsException("No additional data");
}
}
return (T) values[index];
}
boolean hasNext() {
if (readIndex < values.length - 1) {
return readIndex < writeIndex;
} else if (next != null) {
return next.hasNext();
} else {
return false;
}
}
}
private class NodeIterator implements Iterator {
private Node node;
private int readIndex;
private NodeIterator() {
this.node = first;
this.readIndex = this.node.readIndex;
}
@Override
public boolean hasNext() {
do {
if (readIndex < node.values.length - 1) {
return readIndex < node.writeIndex;
} else if (node.next == null) {
return false;
}
node = node.next;
readIndex = -1;
} while (true);
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException("Has no value");
}
if (readIndex < node.readIndex) {
throw new ConcurrentModificationException();
}
return (T) node.values[++readIndex];
}
}
// todo: mtymes - remove
// public static void main(String[] args) {
//
// long startTime = System.currentTimeMillis();
//
// for (int i = 0; i < 10; i++) {
//// List values = new ArrayList<>();
//// List values = newLinkedList();
// Queue values = new LinkedArrayQueue<>(1024);
//// Queue values = new LinkedBlockingQueue<>();
//
// for (int j = 0; j < 102_000_000; j++) {
// values.add(j);
//// values.offer(j);
// }
//
//// while (!values.isEmpty()) {
//// values.remove(0);
////// values.poll();
//// }
// }
//
// long duration = System.currentTimeMillis() - startTime;
//
// System.out.println(Duration.ofMillis(duration));
// }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy