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

javolution.util.Index Maven / Gradle / Ivy

/*
 * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
 * Copyright (C) 2012 - Javolution (http://javolution.org/)
 * All rights reserved.
 * 
 * Permission to use, copy, modify, and distribute this software is
 * freely granted, provided that this notice is preserved.
 */
package javolution.util;

import java.io.IOException;
import java.io.ObjectStreamException;

import javolution.lang.Configurable;
import javolution.lang.MathLib;
import javolution.lang.Realtime;
import javolution.lang.ValueType;
import javolution.text.Cursor;
import javolution.text.DefaultTextFormat;
import javolution.text.TextContext;
import javolution.text.TextFormat;
import javolution.text.TypeFormat;
import javolution.util.internal.table.ConstantTableImpl;

/**
 * 

A non-negative number representing a position in an arrangement. * [code] * interface Vector { * Vector getSubVector(List indices); * // e.g. getSubVector(Index.rangeOf(0, n)) for the n first elements. * ... * }[/code]

*

Index performance is on-par with the primitive {@code int} type * for small values and similar to {@link Integer} instances for large * values. Small indexes have no adverse effect on the garbage collector * and have fast {@link #equals(Object) equals} method due to their unicity.

* * @author Jean-Marie Dautelle * @version 5.1, July 26, 2007 */ @Realtime @DefaultTextFormat(Index.Decimal.class) public final class Index extends Number implements Comparable, ValueType { /** * Default text format for indices (decimal value representation). */ public static class Decimal extends TextFormat { @Override public Appendable format(Index obj, Appendable dest) throws IOException { return TypeFormat.format(obj.intValue(), dest); } @Override public Index parse(CharSequence csq, Cursor cursor) throws IllegalArgumentException { return Index.of(TypeFormat.parseInt(csq, cursor)); } } /** * Holds the number of unique preallocated instances (default {@code 1024}). * This number is configurable, for example with * {@code -Djavolution.util.Index#UNIQUE=0} there is no unique instance. */ public static final Configurable UNIQUE = new Configurable() { @Override protected Integer getDefault() { return 1024; } @Override protected Integer initialized(Integer value) { return MathLib.min(value, 65536); // Hard-limiting } @Override protected Integer reconfigured(Integer oldCount, Integer newCount) { throw new UnsupportedOperationException( "Unicity reconfiguration not supported."); } }; /** * Holds the index zero (value 0). */ public static final Index ZERO = new Index(0); private static final long serialVersionUID = 0x600L; // Version. private static final Index[] INSTANCES = new Index[UNIQUE.get()]; static { INSTANCES[0] = ZERO; for (int i = 1; i < INSTANCES.length; i++) { INSTANCES[i] = new Index(i); } } private static final ConstantTable INSTANCES_TABLE = new ConstantTable( new ConstantTableImpl(INSTANCES)); /** * Returns the index for the specified {@code int} non-negative * value (returns a preallocated instance if the specified value is * small). * * @param value the index value. * @return the corresponding index. * @throws IndexOutOfBoundsException if value < 0 */ public static Index of(int value) { return (value < INSTANCES.length) ? INSTANCES[value] : new Index(value); } /** * Returns the indices having the specified {@code int} non-negative * values (convenience method). * * @param values the indices values. * @return the corresponding table. */ public static FastTable listOf(int... values) { Index[] indices = new Index[values.length]; for (int i = 0; i < indices.length; i++) { indices[i] = Index.of(values[i]); } return new ConstantTable(new ConstantTableImpl(indices)); } /** * Returns the indices having the specified range of {@code int} non-negative * values (convenience method). A sub-table view over preallocated * instances is returned when possible. * * @param fromIndex low endpoint (inclusive) of the list to return. * @param toIndex high endpoint (exclusive) of the list to return. * @return the corresponding indices. */ public static ConstantTable rangeOf(int fromIndex, int toIndex) { if (toIndex <= INSTANCES.length) return INSTANCES_TABLE.subTable(fromIndex, toIndex); // Optimization. Index[] indices = new Index[toIndex - fromIndex]; for (int i = fromIndex, j = 0; i < toIndex; i++) { indices[j++] = Index.of(i); } return new ConstantTable(new ConstantTableImpl(indices)); } /** * Holds the index value. */ private final int value; /** * Creates an index having the specified value. */ private Index(int value) { this.value = value; } /** * Compares this index with the specified index for order. Returns a * negative integer, zero, or a positive integer as this index is less * than, equal to, or greater than the specified index. * * @param that the index to be compared. * @return a negative integer, zero, or a positive integer as this index * is less than, equal to, or greater than the specified index. */ public int compareTo(Index that) { return this.value - that.value; } /** * Compares this index with the specified integer value for order. Returns a * negative integer, zero, or a positive integer as this index is less * than, equal to, or greater than the specified value. * * @param value the value to be compared. * @return a negative integer, zero, or a positive integer as this index * is less than, equal to, or greater than the specified value. */ public int compareTo(int value) { return this.value - value; } /** * Returns a copy of this index or this if the indexes * is small (in permanent memory) in order to maintain unicity. */ public Index copy() { return value < INSTANCES.length ? this : new Index(value); } /** * Returns the index value as double. * * @return the index value. */ public double doubleValue() { return (double) value; } /** * Indicates if this index is equals to the one specified (for small * indices this method is equivalent to ==). */ @Override public boolean equals(Object obj) { return (this.value < INSTANCES.length) ? (this == obj) : ((obj instanceof Index) ? (((Index) obj).value == value) : false); } /** * Returns the index value as float. * * @return the index value. */ public float floatValue() { return (float) value; } /** * Returns the hash code for this index. */ @Override public int hashCode() { return value; } /** * Returns the index value as int. * * @return the index value. */ public int intValue() { return value; } /** * Indicates if this index is zero. * * @return {@code this == ZERO} */ public boolean isZero() { return this == ZERO; } /** * Returns the index value as long. * * @return the index value. */ public long longValue() { return value; } /** * Returns the index after this one. */ public Index next() { return Index.of(value + 1); } /** * Returns the index before this one. * * @throws IndexOutOfBoundsException if (this == Index.ZERO) */ public Index previous() { return Index.of(value - 1); } /** * Ensures index unicity during deserialization. */ protected final Object readResolve() throws ObjectStreamException { return Index.of(value); } /** * Returns the {@link String} representation of this index. * * @return {@code TextContext.getFormat(Index.class).format(this)} */ @Override public String toString() { return TextContext.getFormat(Index.class).format(this); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy