All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.methylene.lists.LookupList Maven / Gradle / Ivy

There is a newer version: 2.0.3
Show newest version
package com.github.methylene.lists;

import com.github.methylene.sym.Permutation;

import java.lang.reflect.Array;
import java.util.*;

/**
 * 

LookupLists are immutable, null-rejecting, array based implementation of {@link java.util.List} * that are optimized for search. Its {@code indexOf}, {@code lastIndexOf} and {@code contains} * methods will often run faster than other array based list implementations.

* *

LookupList stores a sorted array internally, so binary search can be used.

* *

* Consequentially, the list can only contain things that can be compared: * primitives or Comparables. Building a list from arbitrary objects is also possible if a suitable Comparator * is provided.

* *

Instances of this list are slower to create and use more memory than {@link java.util.ArrayList}. * This is because the backing array has to be sorted when the list is created, and for each element in the list, * an extra 8 bytes (two ints) are used to store its original position.

* *

The speedup of the search methods depends on the size of the list, and also on the cost of the * {@code equals} method of its elements.

*/ public abstract class LookupList extends AbstractList implements RandomAccess { static final int[] EMPTY_INT_ARRAY = new int[0]; protected final Permutation unsort; protected final Permutation sort; static int checkNonnegative(int i) { if (i < 0) throw new IllegalArgumentException("negative number is not allowed"); return i; } protected LookupList(Permutation sort, Permutation unsort) { this.sort = sort; this.unsort = unsort; } protected LookupList(Permutation sort) { this(sort, sort.invert()); } /** * Return a new list that contains the elements of this list in natural order. * @return the sorted list */ public abstract List sort(); /** * Returns a new list that contains the elements of this list in natural order, * with duplicates removed. * @return the unique sorted list */ public abstract List sortUnique(); /** * Group the elements in this list. * This returns a map where each distinct value in the list is mapped to an array of all the indexes * where it appears. This array of indexes is in ascending order. * @return the grouped list */ public abstract Map group(); public abstract LookupList shuffle(Permutation p); public abstract boolean isUnique(); public abstract boolean isSorted(); /** * Find at most {@code size} indexes {@code i} where *

   *   this.get(i).equals(el)
   * 
*

The return value is in natural order.

*

This method could be used to find duplicates in the list as follows:

*

   *   public  E findDuplicate(LookupList list) {
   *     for (E el: list) {
   *       if (list.indexOf(el, 2).length == 2) {
   *         return el;
   *       }
   *     }
   *     return null;
   *   }
   * 
* If {@code size < 0}, all indexes of {@code el} are returned. * If {@code el} is not in the list, this returns an empty array. * @param el an object * @param size a number * @return an array of length {@code size} or less, or an array of all indexes of {@code el} if {@code size < 0} */ public abstract int[] indexOf(E el, int size); /** * Creates a primitive list from the given input. * @param a an array * @return a list representation of the input */ @SuppressWarnings("unchecked") public static LookupList of(int... a) { switch (a.length) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(a[0]); default: return IntList.createNewList(a, Permutation.sort(a)); } } /** * Creates a primitive list from the given input. * @param a an array * @return a list representation of the input */ @SuppressWarnings("unchecked") public static LookupList of(long... a) { switch (a.length) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(a[0]); default: return LongList.createNewList(a, Permutation.sort(a)); } } /** * Creates a primitive list from the given input. * @param a an array * @return a list representation of the input */ @SuppressWarnings("unchecked") public static LookupList of(byte... a) { switch (a.length) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(a[0]); default: return ByteList.createNewList(a, Permutation.sort(a)); } } /** * Creates a primitive list from the given input. * @param a an array * @return a list representation of the input */ @SuppressWarnings("unchecked") public static LookupList of(char... a) { switch (a.length) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(a[0]); default: return CharList.createNewList(a, Permutation.sort(a)); } } /** * Creates a primitive list from the given input. * @param a an array * @return a list representation of the input */ @SuppressWarnings("unchecked") public static LookupList of(float... a) { switch (a.length) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(a[0]); default: return FloatList.createNewList(a, Permutation.sort(a)); } } /** * Creates a primitive list from the given input. * @param a an array * @return a list representation of the input */ @SuppressWarnings("unchecked") public static LookupList of(double... a) { switch (a.length) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(a[0]); default: return DoubleList.createNewList(a, Permutation.sort(a)); } } /** * Creates a primitive list from the given input. * @param a an array * @return a list representation of the input */ @SuppressWarnings("unchecked") public static LookupList of(short... a) { switch (a.length) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(a[0]); default: return ShortList.createNewList(a, Permutation.sort(a)); } } /** * Returns the empty list. * @return the empty list */ @SuppressWarnings("unchecked") public static LookupList of() { return (LookupList) EmptyLookupList.INSTANCE; } /** * Creates a list from the given input. * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0) { return new SingleElementLookupList(e0); } /** * Creates a list from the given input. * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1) { return new ComparableList.Builder(2).add(e0).add(e1).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2) { return new ComparableList.Builder(3).add(e0).add(e1).add(e2).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2, E e3) { return new ComparableList.Builder(4).add(e0).add(e1).add(e2).add(e3).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2, E e3, E e4) { return new ComparableList.Builder(5).add(e0).add(e1).add(e2).add(e3).add(e4).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2, E e3, E e4, E e5) { return new ComparableList.Builder(6).add(e0).add(e1).add(e2).add(e3).add(e4).add(e5).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2, E e3, E e4, E e5, E e6) { return new ComparableList.Builder(7).add(e0).add(e1).add(e2).add(e3).add(e4).add(e5).add(e6).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2, E e3, E e4, E e5, E e6, E e7) { return new ComparableList.Builder(8).add(e0).add(e1).add(e2).add(e3).add(e4).add(e5).add(e6).add(e7).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { return new ComparableList.Builder(9).add(e0).add(e1).add(e2).add(e3).add(e4).add(e5).add(e6).add(e7).add(e8).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { return new ComparableList.Builder(10).add(e0).add(e1).add(e2).add(e3).add(e4).add(e5).add(e6).add(e7).add(e8).add(e9).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { return new ComparableList.Builder(11).add(e0).add(e1).add(e2).add(e3).add(e4).add(e5).add(e6).add(e7).add(e8).add(e9).add(e10).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ public static LookupList of(E e0, E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E... es) { return new ComparableList.Builder(11 + es.length).add(e0).add(e1).add(e2).add(e3).add(e4).add(e5).add(e6).add(e7).add(e8).add(e9).add(e10).addAll(es).build(); } /** * Creates a list from the given input. * * @throws java.lang.NullPointerException if the input contains a {@code null} element */ @SuppressWarnings("unchecked") public static LookupList copyOf(E[] a) { switch (a.length) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(a[0]); default: return ComparableList.createNewList(a, Permutation.sort(a)); } } /** * Create a new list from the given input. If the input is already an instance of LookupList, it is returned unchanged. * @param list a list * @return a LookupList */ @SuppressWarnings("unchecked") public static LookupList copyOf(Collection list) { if (list instanceof LookupList) return (LookupList) list; switch (list.size()) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(list.iterator().next()); default: ComparableList.Builder builder = new ComparableList.Builder(list.size()); builder.addAll(list); return builder.build(); } } /** * Create a new list from the given input. * @param iterable a iterable * @return a LookupList */ public static LookupList copyOf(Iterable iterable) { if (iterable instanceof LookupList) return (LookupList) iterable; return copyOf(iterable.iterator()); } /** * Create a new list from the given input. * @param iterator a iterator * @return a LookupList */ @SuppressWarnings("unchecked") public static LookupList copyOf(Iterator iterator) { if (!iterator.hasNext()) return (LookupList) EmptyLookupList.INSTANCE; E first = iterator.next(); if (!iterator.hasNext()) return new SingleElementLookupList(first); ComparableList.Builder builder = new ComparableList.Builder(); builder.add(first); while (iterator.hasNext()) builder.add(iterator.next()); return builder.build(); } /** * Creates a list from the given input. * @param comparator a comparator * @param a an array * @return a list representation of the input * @throws java.lang.NullPointerException if the input contains a {@code null} element */ @SuppressWarnings("unchecked") public static LookupList copyOf(Comparator comparator, E[] a) { if (comparator == null) throw new IllegalArgumentException("comparator can not be null"); switch (a.length) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(a[0]); default: return ComparatorList.createNewList(comparator, a, Permutation.sort(a, comparator)); } } /** * Create a new list from the given input. If the input is already an instance of LookupList, it is returned unchanged. * @param comparator a comparator * @param list a list * @return a LookupList */ @SuppressWarnings("unchecked") public static LookupList copyOf(Comparator comparator, Collection list) { if (list instanceof LookupList) return (LookupList) list; switch (list.size()) { case 0: return (LookupList) EmptyLookupList.INSTANCE; case 1: return new SingleElementLookupList(list.iterator().next()); default: ComparatorList.Builder builder = new ComparatorList.Builder(comparator, list.size()); builder.addAll(list); return builder.build(); } } /** * Create a new list from the given input. * @param comparator a comparator * @param iterable a iterable * @return a LookupList */ public static LookupList copyOf(Comparator comparator, Iterable iterable) { if (iterable instanceof LookupList) return (LookupList) iterable; return copyOf(comparator, iterable.iterator()); } /** * Create a new list from the given input. * @param comparator a comparator * @param iterator a iterator * @return a LookupList */ @SuppressWarnings("unchecked") public static LookupList copyOf(Comparator comparator, Iterator iterator) { if (!iterator.hasNext()) return (LookupList) EmptyLookupList.INSTANCE; E first = iterator.next(); if (!iterator.hasNext()) return new SingleElementLookupList(first); ComparatorList.Builder builder = new ComparatorList.Builder(comparator); builder.add(first); while (iterator.hasNext()) builder.add(iterator.next()); return builder.build(); } /** * Create a list builder. * @param comparator a comparator * @return a new builder */ public static ListBuilder builder(Comparator comparator) { return new ComparatorList.Builder(comparator); } /** * Create a list builder. * @param comparator a comparator * @param initialCapacity initial builder capacity * @return a new builder */ public static ListBuilder builder(Comparator comparator, int initialCapacity) { return new ComparatorList.Builder(comparator, initialCapacity); } /** * Create a list builder. * @return a new builder */ public static ListBuilder builder() { return new ComparableList.Builder(); } /** * Create a list builder. * @param initialCapacity initial builder capacity * @return a new builder */ public static ListBuilder builder(int initialCapacity) { return new ComparableList.Builder(initialCapacity); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy