All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.methylene.lists.ComparatorList Maven / Gradle / Ivy
package com.github.methylene.lists;
import static com.github.methylene.lists.ListBuilder.DEFAULT_INITIAL_CAPACITY;
import static com.github.methylene.lists.ListBuilder.ensureCapacity;
import static com.github.methylene.sym.Rankings.apply;
import static com.github.methylene.sym.Rankings.nextOffset;
import static com.github.methylene.sym.Rankings.sort;
import static java.util.Arrays.copyOf;
import com.github.methylene.sym.Permutation;
import com.github.methylene.sym.Util;
import java.io.Serializable;
import java.util.*;
/**
* Comparator based lookup list.
*/
public final class ComparatorList extends LookupList implements RandomAccess, Serializable {
private static final long serialVersionUID = 1L;
private final Object[] sorted;
private final Comparator comparator;
private final boolean unique;
private final boolean ordered;
private ComparatorList(Object[] sorted, boolean ordered, Permutation sort, Permutation unsort, Comparator comparator) {
super(sort, unsort);
this.comparator = comparator;
this.sorted = sorted;
this.ordered = ordered;
this.unique = Util.isUnique(sorted);
}
static ComparatorList createNewList(Comparator comparator, Object[] a, Permutation sort) {
Object[] applied = sort.apply(a);
Object[] sorted = applied == a ? Arrays.copyOf(a, a.length) : applied;
return new ComparatorList(sorted, Util.isSorted(comparator, a), sort, sort.invert(), comparator);
}
public static ComparatorList createNewList(Comparator comparator, Object[] a) {
return createNewList(comparator, a, Permutation.sort(a, comparator));
}
/**
* Get the comparator used by this instance.
* @return the comparator
*/
public Comparator getComparator() {
return comparator;
}
@Override
public int indexOf(Object el) {
@SuppressWarnings("unchecked")
int i = Arrays.binarySearch(sorted, el, (Comparator) comparator);
return i < 0 ? -1 : unsort.apply(i);
}
@Override
public int lastIndexOf(Object el) {
@SuppressWarnings("unchecked")
int start = Arrays.binarySearch(sorted, el, (Comparator) comparator);
if (start < 0) {return -1;}
int direction = start > 0 && Objects.equals(sorted[start - 1], el) ? -1 : 1;
int peek = start + direction;
while (peek >= 0 && peek < sorted.length && Objects.equals(sorted[peek], el)) {
start = peek;
peek += direction;
}
return unsort.apply(start);
}
@Override
public boolean contains(Object el) {
return indexOf(el) >= 0;
}
@Override
@SuppressWarnings("unchecked")
public E get(int i) {
return (E) sorted[sort.apply(i)];
}
@Override
public int size() {
return sorted.length;
}
@Override
public int[] indexOf(E el, int size) {
@SuppressWarnings("unchecked")
final int idx = Arrays.binarySearch(sorted, el, (Comparator) comparator);
if (idx < 0)
return EMPTY_INT_ARRAY;
int[] builder = new int[size < 0 ? DEFAULT_INITIAL_CAPACITY : size];
int offset = 0;
int i = 0;
do {
builder = ensureCapacity(builder, i + 1);
builder[i++] = unsort.apply(idx + offset);
} while ((offset = nextOffset(idx, offset, sorted)) != 0 && (size < 0 || i < size));
return i == size ? builder : Arrays.copyOf(builder, i);
}
@Override
public Map group() {
return Group.group(sorted, unsort);
}
@Override
@SuppressWarnings("unchecked")
public List sort() {
if (ordered)
return this;
ArrayList result = new ArrayList(sorted.length);
for (Object el : sorted)
result.add((E) el);
return result;
}
@Override
@SuppressWarnings("unchecked")
public List sortUnique() {
if (unique)
return sort();
ArrayList result = new ArrayList(sorted.length);
E previous = (E) sorted[0];
for (Object el : sorted) {
if (!el.equals(previous)) {
result.add(previous);
previous = (E) el;
}
}
result.add(previous);
return result;
}
@Override
public ComparatorList shuffle(Permutation p) {
if (unique) {
Permutation punsort = p.compose(unsort);
return new ComparatorList(sorted, punsort.sorts(comparator, sorted), punsort.invert(), punsort, comparator);
} else {
Object[] a = p.compose(super.unsort).apply(sorted);
return createNewList(comparator, a, Permutation.sort(a, comparator));
}
}
@Override
public boolean isUnique() {
return unique;
}
@Override
public boolean isSorted() {
return ordered;
}
/**
* Convenience list builder
*/
public static final class Builder extends ListBuilder {
private final Comparator comparator;
private Object[] contents;
Builder(Comparator comparator, int initialCapacity) {
this.comparator = comparator;
this.contents = new Comparable[checkPositive(initialCapacity)]; }
Builder(Comparator comparator) {
this(comparator, DEFAULT_INITIAL_CAPACITY);
}
@Override
@SuppressWarnings("unchecked")
public ComparatorList build() {
Object[] a = Arrays.copyOf(contents, size);
return createNewList(comparator, a, Permutation.sort(a, (Comparator) comparator));
}
@Override
protected void ensureCapacity(int minCapacity) {
if (minCapacity > contents.length)
contents = ensureCapacity(contents, minCapacity);
}
@Override
public Builder add(E el) {
ensureCapacity(size + 1);
contents[size++] = el;
return this;
}
@Override public ListBuilder addAll(E... elements) {
ensureCapacity(size + elements.length);
System.arraycopy(elements, 0, contents, size, elements.length);
incrementSize(elements.length);
return this;
}
}
}