javolution.text.CharArray Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javolution-core-java-msftbx Show documentation
Show all versions of javolution-core-java-msftbx Show documentation
Only the Java Core part of Javolution library, with slight modifications for use in MSFTBX.
/*
* 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.text;
import javolution.util.function.Equalities;
/**
* A {@link CharSequence} backed up by a char
array.
* Instances of this class are
* typically used/reused to provide CharSequence
views
* over existing character buffers.
*
* Instances of this classes have the following properties:
*
* - They support equality or lexical comparison with any
*
CharSequence
(e.g. String
).
*
* - They have the same hashcode than
String
and can be
* used to retrieve data from maps for which the keys are
* String
instances.
*
* - They support fast conversions to primitive types
* (e.g. {@link #toBoolean() Boolean}, {@link #toInt int}).
*
*
*
* @author Jean-Marie Dautelle
* @version 5.3, January 10, 2007
*/
public final class CharArray implements CharSequence, Comparable {
/**
* Holds the character array.
*/
private char[] _array;
/**
* Holds the index of the first character.
*/
private int _offset;
/**
* Holds the length of char sequence.
*/
private int _length;
/**
* Default constructor (empty character array).
*/
public CharArray() {
_array = NO_CHAR;
}
private static final char[] NO_CHAR = new char[0];
/**
* Creates a character array of specified default capacity.
*
* @param capacity the backing array default capacity.
*/
public CharArray(int capacity) {
_array = new char[capacity];
}
/**
* Creates a character array from the specified String.
*
* @param string the string source.
*/
public CharArray(String string) {
_array = string.toCharArray();
_length = string.length();
}
/**
* Returns the underlying array.
*
* @return the underlying array.
*/
public char[] array() {
return _array;
}
/**
* Returns the length of this character sequence.
*
* @return the number of characters (16-bits Unicode).
*/
public int length() {
return _length;
}
/**
* Returns the offset of the first character in the underlying array.
*
* @return the offset of the first character.
*/
public int offset() {
return _offset;
}
/**
* Sets the underlying array of this CharArray.
*
* @param offset the new offset.
* @param array the new underlying array.
* @param length the new length.
* @return this
*/
public CharArray setArray(char[] array, int offset, int length) {
_array = array;
_offset = offset;
_length = length;
return this;
}
/**
* Returns the index within this character sequence of the first occurrence
* of the specified characters sequence searching forward..
*
* @param csq a character sequence searched for.
* @return the index of the specified character sequence in the range
* [0, length()[
* or -1
if the character sequence is not found.
*/
public final int indexOf(java.lang.CharSequence csq) {
return indexOf(csq, 0);
}
/**
* Returns the index within this character sequence of the first occurrence
* of the specified characters sequence searching forward, starting from the
* specified index
*
* @param csq a character sequence searched for.
* @param fromIndex the index to start searching from
* @return the index of the specified character sequence in the range
* [0, length()[
* or -1
if the character sequence is not found.
* @throws IndexOutOfBoundsException Thrown if from index is out of bounds of the view of the backing array
*/
public final int indexOf(java.lang.CharSequence csq, int fromIndex) {
if((_offset + fromIndex + csq.length() - 1) >= (_offset + _length))
throw new IndexOutOfBoundsException(String.format("From Index %d Is Out of Bounds", fromIndex));
final char c = csq.charAt(0);
final int csqLength = csq.length();
for (int i = _offset + fromIndex, end = _offset + _length - csqLength + 1; i < end; i++) {
if (_array[i] == c) { // Potential match.
boolean match = true;
for (int j = 1; j < csqLength; j++) {
if (_array[i + j] != csq.charAt(j)) {
match = false;
break;
}
}
if (match) { return i - _offset; }
}
}
return -1;
}
/**
* Returns the index within this character sequence of the first occurrence
* of the specified character searching forward.
*
* @param c the character to search for.
* @return the indext of the specified character in the range
* [0, length()[
* or -1
if the character is not found.
*/
public final int indexOf(char c) {
return indexOf(c, 0);
}
/**
* Returns the index within this character sequence of the first occurrence
* of the specified character searching forward, starting from the specified
* index.
*
* @param c the character to search for.
* @param fromIndex the index to start searching from
* @return the indext of the specified character in the range
* [0, length()[
* or -1
if the character is not found.
* @throws IndexOutOfBoundsException Thrown if from index is out of bounds of the view of the backing array
*/
public final int indexOf(char c, int fromIndex) {
if((_offset + fromIndex) >= (_offset + _length))
throw new IndexOutOfBoundsException(String.format("From Index %d Is Out of Bounds", fromIndex));
for (int i = _offset + fromIndex, end = _offset + _length; i < end; i++) {
if (_array[i] == c) return i - _offset;
}
return -1;
}
/**
* Returns the index within this character sequence of the last occurrence
* of the specified characters sequence searching backwards.
*
* @param csq a character sequence searched for.
* @return the index of the specified character sequence in the range
* [0, length()[
* or -1
if the character sequence is not found.
*/
public final int lastIndexOf(java.lang.CharSequence csq) {
return lastIndexOf(csq, 0);
}
/**
* Returns the index within this character sequence of the last occurrence
* of the specified characters sequence searching backward, starting from the
* specified index
*
* @param csq a character sequence searched for.
* @param fromIndex the index to start searching from
* @return the index of the specified character sequence in the range
* [0, length()[
* or -1
if the character sequence is not found.
* @throws IndexOutOfBoundsException Thrown if from index is out of bounds of the view of the backing array
*/
public final int lastIndexOf(java.lang.CharSequence csq, int fromIndex) {
if((_offset + fromIndex + csq.length() - 1) >= (_offset + _length))
throw new IndexOutOfBoundsException(String.format("From Index %d Is Out of Bounds", fromIndex));
final char c = csq.charAt(0);
final int csqLength = csq.length();
for (int i = _length + _offset - csqLength - fromIndex, end = _offset; i >= end; i--) {
if (_array[i] == c) { // Potential match.
boolean match = true;
for (int j = 1; j < csqLength; j++) {
if (_array[i + j] != csq.charAt(j)) {
match = false;
break;
}
}
if (match) { return i - _offset; }
}
}
return -1;
}
/**
* Returns the index within this character sequence of the last occurrence
* of the specified character searching backwards.
*
* @param c the character to search for.
* @return the indext of the specified character in the range
* [0, length()[
* or -1
if the character is not found.
*/
public final int lastIndexOf(char c) {
return lastIndexOf(c, _length - 1);
}
/**
* Returns the index within this character sequence of the last occurrence
* of the specified character searching backwards, starting from the specified
* index.
*
* @param c the character to search for
* @param fromIndex the index to start searching from.
* @return the indext of the specified character in the range
* [0, length()[
* or -1
if the character is not found.
* @throws IndexOutOfBoundsException Thrown if from index is out of bounds of the view of the backing array
*/
public final int lastIndexOf(char c, int fromIndex) {
if((_offset + fromIndex) >= (_offset + _length))
throw new IndexOutOfBoundsException(String.format("From Index %d Is Out of Bounds", fromIndex));
for (int i = _offset + fromIndex, end = _offset; i >= end; i--) {
if (_array[i] == c) return i - _offset;
}
return -1;
}
/**
* Returns the String
corresponding to this character
* sequence. The String
returned is always allocated on the
* heap and can safely be referenced elsewhere.
*
* @return the java.lang.String
for this character sequence.
*/
@Override
public String toString() {
return new String(_array, _offset, _length);
}
/**
* Returns the hash code for this {@link CharArray}.
*
* Note: Returns the same hashCode as java.lang.String
* (consistent with {@link #equals})
* @return the hash code value.
*/
@Override
public int hashCode() {
int h = 0;
for (int i = 0, j = _offset; i < _length; i++) {
h = 31 * h + _array[j++];
}
return h;
}
/**
* Compares this character sequence against the specified object
* (String
or CharSequence
).
*
* @param that the object to compare with.
* @return true
if both objects represent the same sequence;
* false
otherwise.
*/
@Override
public boolean equals(Object that) {
if (that instanceof String) {
return equals((String) that);
} else if (that instanceof CharArray) {
return equals((CharArray) that);
} else if (that instanceof java.lang.CharSequence) {
return contentEquals((java.lang.CharSequence) that);
} else {
return false;
}
}
/**
* Compares this character array against the specified character sequence.
*
* @param chars the character sequence to compare with.
* @return true
if both objects represent the same sequence;
* false
otherwise.
*/
public boolean contentEquals(CharSequence chars) {
if (chars == null) return false;
if (this._length != chars.length()) return false;
for (int i = _length, j = _offset + _length; --i >= 0;) {
if (_array[--j] != chars.charAt(i)) return false;
}
return true;
}
/**
* Compares this character array against the specified {@link CharArray}.
*
* @param that the character array to compare with.
* @return true
if both objects represent the same sequence;
* false
otherwise.
*/
public boolean equals(CharArray that) {
if (this == that) return true;
if (that == null) return false;
if (this._length != that._length) return false;
final char[] thatArray = that._array;
for (int i = that._offset + _length, j = _offset + _length; --j >= _offset;) {
if (_array[j] != thatArray[--i]) return false;
}
return true;
}
/**
* Compares this character array against the specified String.
* In case of equality, the CharArray keeps a reference to the
* String for future comparisons.
*
* @param str the string to compare with.
* @return true
if both objects represent the same sequence;
* false
otherwise.
*/
public boolean equals(String str) {
if (str == null) return false;
if (_length != str.length()) return false;
for (int i = _length, j = _offset + _length; --i >= 0;) {
if (_array[--j] != str.charAt(i)) return false;
}
return true;
}
/**
* Compares this character array with the specified character
* sequence lexicographically.
*
* @param seq the character sequence to be compared.
* @return {@link Equalities#LEXICAL}.compare(this, seq)
* @throws ClassCastException if the specifed object is not a
* CharSequence
.
*/
public int compareTo(CharSequence seq) {
return Equalities.LEXICAL.compare(this, seq);
}
/**
* Returns the boolean
represented by this character array.
*
* @return the corresponding boolean
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable boolean
.
*/
public boolean toBoolean() {
return TypeFormat.parseBoolean(this);
}
/**
* Returns the decimal int
represented by this character array.
*
* @return toInt(10)
* @throws NumberFormatException if this character sequence
* does not contain a parsable int
.
*/
public int toInt() {
return TypeFormat.parseInt(this);
}
/**
* Returns the int
represented by this character array
* in the specified radix.
*
* @param radix the radix (e.g. 16
for hexadecimal).
* @return the corresponding int
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable int
.
*/
public int toInt(int radix) {
return TypeFormat.parseInt(this, radix);
}
/**
* Returns the decimal long
represented by this character
* array.
*
* @return the corresponding long
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable long
.
*/
public long toLong() {
return TypeFormat.parseLong(this);
}
/**
* Returns the decimal long
represented by this character
* array in the specified radix.
*
* @param radix the radix (e.g. 16
for hexadecimal).
* @return the corresponding long
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable long
.
*/
public long toLong(int radix) {
return TypeFormat.parseLong(this, radix);
}
/**
* Returns the float
represented by this character array.
*
* @return the corresponding float
value.
* @return TypeFormat.parseFloat(this)
* @throws NumberFormatException if this character sequence
* does not contain a parsable float
.
*/
public float toFloat() {
return TypeFormat.parseFloat(this);
}
/**
* Returns the double
represented by this character array.
*
* @return the corresponding double
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable double
.
*/
public double toDouble() {
return TypeFormat.parseDouble(this);
}
// Implements CharSequence
public char charAt(int index) {
if ((index < 0) || (index >= _length)) throw new IndexOutOfBoundsException(
"index: " + index);
return _array[_offset + index];
}
// Implements CharSequence
public java.lang.CharSequence subSequence(int start, int end) {
if ((start < 0) || (end < 0) || (start > end) || (end > this.length())) throw new IndexOutOfBoundsException();
CharArray chars = new CharArray();
chars._array = _array;
chars._offset = _offset + start;
chars._length = end - start;
return chars;
}
// Implements CharSequence
public void getChars(int start, int end, char dest[], int destPos) {
if ((start < 0) || (end < 0) || (start > end) || (end > _length)) throw new IndexOutOfBoundsException();
System.arraycopy(_array, start + _offset, dest, destPos, end - start);
}
}