/*license*\
XBN-Java: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com)
This software is dual-licensed under the:
- Lesser General Public License (LGPL) version 3.0 or, at your option, any later version;
- Apache Software License (ASL) version 2.0.
Either license may be applied at your discretion. More information may be found at
- http://en.wikipedia.org/wiki/Multi-licensing.
The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at:
- LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
- ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
\*license*/
package com.github.xbn.array;
import com.github.xbn.array.NullContainer;
import com.github.xbn.lang.CrashIfObject;
import com.github.xbn.util.copyval.ValueCopier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
<p>Utilities related to non-primitive arrays, including error checking and conversion to other non-primitive containers.</p>
* @since 0.1.0
* @author Copyright (C) 2014, Jeff Epstein ({@code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <a href="http://xbnjava.aliteralmind.com">{@code http://xbnjava.aliteralmind.com}</a>, <a href="https://github.com/aliteralmind/xbnjava">{@code https://github.com/aliteralmind/xbnjava}</a>
**/
public class ArrayUtil {
public static final StringBuilder[] asdEMPTY = new StringBuilder[0];
/**
<p>Same as <code>Arrays.toString</code>, with the addition of highlighting a single element.</p>
* @return <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#appendToString(java.lang.StringBuilder, E[], java.lang.String, int, java.lang.String)">appendToString</a>(new StringBuilder(), array, prefix, index, postfix).toString()</code>
*/
public static final <E> String toStringHighlightElement(E[] array, String prefix, int index, String postfix) {
return appendToStringHighlightElement(new StringBuilder(), array, prefix, index, postfix).toString();
}
/**
<p>Same as <code>{@link java.util.Arrays}.{@link java.util.Arrays#toString(Object[]) toString}</code>, with the addition of highlighting a single element.</p>
* @param to_appendTo May not be {@code null}.
* @param array May not be {@code null}.
* @param prefix Placed before the highlighted element. <i>Should</i> not be {@code null} or empty.
* @param index The element to highlight. <i>Should</i> be a valid index.
* @param postfix Placed after the highlighted element.
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#toStringHighlightElement(E[], java.lang.String, int, java.lang.String)">toStringHighlightElement</a></code>
*/
public static final <E> StringBuilder appendToStringHighlightElement(StringBuilder to_appendTo, E[] array, String prefix, int index, String postfix) {
try {
// int lenMinus1 = array.length - 1;
for(int i = 0; i < array.length; i++) {
if(i == index) {
to_appendTo.append(prefix);
}
to_appendTo.append(array[i]);
if(i == index) {
to_appendTo.append(postfix);
}
if(i < array.length - 1) {
to_appendTo.append(", ");
}
}
} catch(RuntimeException rx) {
CrashIfObject.nnull(to_appendTo, "to_appendTo", null);
throw CrashIfObject.nullOrReturnCause(array, "array", null, rx);
}
return to_appendTo;
}
/**
<p>Get the length of an array, or crash if it's {@code null}.</p>
* @param array The array whose length is needed.
* @param array_name Descriptive name of {@code coll}. <i>Should</i> be non-{@code null} and non-empty.
* @return {@code array.length}
* @exception NullPointerException If {@code array} is {@code null}.
*/
public static final <E> int getLengthCrashIfNull(E[] array, String array_name) {
try {
return array.length;
} catch(RuntimeException rx) {
throw CrashIfObject.nullOrReturnCause(array, array_name, null, rx);
}
}
/**
<p>Get a new non-primitive array, from another of a potentially different type.</p>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#getObjectArrayOrNull(E[], xbn.util.copyval.ValueCopier, boolean, java.lang.String)">getObjectArrayOrNull</a>(E[],vc,b,s)</code>
*/
public static final <U,T> T[] getArrayCopyNewType(U[] original, Class<? extends T[]> new_type) {
if(original == null) {
return null;
}
try {
return Arrays.copyOf(original, original.length, new_type);
} catch(RuntimeException rx) {
throw CrashIfObject.nullOrReturnCause(new_type, "new_type", null, rx);
}
}
/**
<p>Get a new object array from a non-primitive array.</p>
* @param get_valCopy If non-{@code null}, all elements are duplicated. When {@code null}, the original elements are referenced. When non-{@code null}, <code>get_valCopy.{@link com.github.xbn.util.copyval.ValueCopier#isValueCopyable() isValueCopyable}()</code> must be {@code true}.
* @param nnull If non-{@code null}, {@code array} may not be {@code null}. This is the name of the function calling this one. It <i>should</i> not be empty.
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#getStringListOrNull(E[], java.lang.String, java.lang.String)">getStringListOrNull</a>(E[],s,s)</code>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#getObjectListOrNull(E[], xbn.util.copyval.ValueCopier, java.lang.String, java.lang.String)">getObjectListOrNull</a>(E[],vc,s,s)</code>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#getListOrNull(E[], xbn.util.copyval.ValueCopier, java.lang.String, java.lang.String)">getListOrNull</a>(E[],vc,s,s)</code>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#getArrayCopyNewType(U[], java.lang.Class)">getArrayCopyNewType</a>(U[],cls)</code>
*/
public static final <E> Object[] getObjectArrayOrNull(E[] array, ValueCopier<E> get_valCopy, NullContainer nnull, String cntrName_forNullBad) {
if(array == null) {
IndexableUtil.crashIfContainerIsNullAndThatIsBad(nnull, cntrName_forNullBad);
return null;
}
if(get_valCopy == null) {
return (Arrays.asList(array).toArray(new Object[array.length]));
}
Object[] ao = new Object[array.length];
for(int i = 0; i < ao.length; i++) {
ao[i] = (Object)get_valCopy.getValueCopy(array[i], "array[i]");
}
return ao;
}
/**
<p>Get a new string array from a non-primitive array.</p>
* @param array The array to convert.
* @param nnull If {@code false}, then {@code array} may not be {@code null}.
* @param cntrName_forNullBad Descriptive name for {@code array}. When {@code null_ok} is {@code true}, this is ignored.
* @return If {@code array} is<ul>
<li>{@code null}: {@code null}</li>
<li>Non-{@code null}: A new string array containing each element's {@code toString()}, in the same order. If an element is {@code null}, it's corresponding element in the returned array is also {@code null}.</li>
</ul>
*/
public static final <E> String[] getStringArrayOrNull(E[] array, NullContainer nnull, String cntrName_forNullBad) {
if(array == null) {
IndexableUtil.crashIfContainerIsNullAndThatIsBad(nnull, cntrName_forNullBad);
return null;
}
String[] as = new String[array.length];
for(int i = 0; i < array.length; i++) {
E e = array[i];
as[i] = ((e == null) ? null : e.toString());
}
return as;
}
/**
<p>Get the middle index of a non-primitive array.</p>
* @param array May not be {@code null}.
* @return <code>{@link com.github.xbn.array.IndexableUtil IndexableUtil}.{@link com.github.xbn.array.IndexableUtil#getMiddleIndex(int) getMiddleIndex}(array.length)</code>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#getNonPArrayElementTSLengthIterator(E[])">getNonPArrayElementTSLengthIterator</a>(E[])</code>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#forIsElementValid(R[], xbn.analyze.validate.ValueValidator)">forIsElementValid</a>(R[],vv)</code>
*/
public static final <E> int getMiddleIndex(E[] array) {
try {
return IndexableUtil.getMiddleIndex(array.length);
} catch(RuntimeException rx) {
throw CrashIfObject.nullOrReturnCause(array, "array", null, rx);
}
}
/**
<p>Get a string list from a non-primitive array.</p>
* @param array The array to convert.
* @param nnull If {@code false}, then {@code array} may not be {@code null}.
* @param cntrName_forNullBad Descriptive name for {@code array}. When {@code null_ok} is {@code true}, this is ignored.
* @return If {@code array} is<ul>
<li>{@code null}: {@code null}</li>
<li>Non-{@code null}: A new list of strings, containing every element's {@code toString()}, or {@code null} if it's {@code null}.</li>
</ul>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#getObjectArrayOrNull(E[], xbn.util.copyval.ValueCopier, boolean, java.lang.String)">getObjectArrayOrNull</a>(E[],vc,b,s)</code>
*/
public static final <E> List<String> getStringListOrNull(E[] array, NullContainer nnull, String cntrName_forNullBad) {
if(array == null) {
IndexableUtil.crashIfContainerIsNullAndThatIsBad(nnull, cntrName_forNullBad);
return null;
}
ArrayList<String> vs = new ArrayList<String>(array.length);
for(int i = 0; i < array.length; i++) {
E o = array[i];
vs.add(((o == null) ? null : o.toString()));
}
return vs;
}
/**
<p>Get an object list from a non-primitive array.</p>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#getObjectArrayOrNull(E[], xbn.util.copyval.ValueCopier, boolean, java.lang.String)">getObjectArrayOrNull</a>(E[],vc,b,s)</code>
*/
public static final <E> List<Object> getObjectListOrNull(E[] array, ValueCopier<E> get_valCopy, NullContainer nnull, String cntrName_forNullBad) {
if(array == null) {
IndexableUtil.crashIfContainerIsNullAndThatIsBad(nnull, cntrName_forNullBad);
return null;
}
ArrayList<Object> vs = new ArrayList<Object>(array.length);
if(get_valCopy == null) {
for(int i = 0; i < array.length; i++) {
vs.add((Object)array[i]);
}
} else {
for(int i = 0; i < array.length; i++) {
vs.add((Object)get_valCopy.getValueCopy(array[i], "array[i]"));
}
}
return vs;
}
/**
<p>Get a list of the element-type, from a non-primitive array.</p>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="#getObjectArrayOrNull(E[], xbn.util.copyval.ValueCopier, boolean, java.lang.String)">getObjectArrayOrNull</a>(E[],vc,b,s)</code>
*/
public static final <E> List<E> getListOrNull(E[] array, ValueCopier<E> get_valCopy, NullContainer nnull, String cntrName_forNullBad) {
if(array == null) {
IndexableUtil.crashIfContainerIsNullAndThatIsBad(nnull, cntrName_forNullBad);
return null;
}
if(get_valCopy == null) {
return Arrays.asList(array);
} else {
ArrayList<E> ve = new ArrayList<E>(array.length);
for(int i = 0; i < array.length; i++) {
ve.add(get_valCopy.getValueCopy(array[i], "array[i]"));
}
return ve;
}
}
public static final <E> E getElementOrCrash(E[] array, int index, String array_name) {
try {
return array[index];
} catch(ArrayIndexOutOfBoundsException abx) {
throw new ArrayIndexOutOfBoundsException("index (" + index + ") invalid given " + array_name + ".length is " + array.length + ".");
}
}
/*
<p>Get a list containing a primitive array's elements, in its wrapper-type, or {@code null} if it's {@code null}.</p>
* @param nnull If non-{@code null}, then {@code array} may not be {@code null}. This is used for the potential error message, and <i>should</i> not be empty.
* @return If {@code array} is<ul>
<li>{@code null}: {@code null}</li>
<li>non-{@code null}:
<br/> {@code Arrays.asList(array)}</li>
</ul>
public static final <E> List<E> getListOrNull(E[] array, NullContainer nnull, String cntrName_forNullBad) {
if(array == null) {
IndexableUtil.crashIfContainerIsNullAndThatIsBad(nnull, cntrName_forNullBad);
return null;
}
return Arrays.asList(array);
}
*/
/*
<p>Get a {@code java.util.List<Object>} containing all elements from a primitive array.</p>
* @param nnull If non-{@code null}, then {@code array} may not be {@code null}. This is used for the potential error message, and <i>should</i> not be empty.
* @return If {@code array} is<ul>
<li>{@code null}: {@code null}</li>
<li>non-{@code null}: A new object-list, containing all elements from {@code array}</li>
</ul>
public static final <E> List<Object> getObjectListOrNull(E[] array, NullContainer nnull, String cntrName_forNullBad) {
if(array == null) {
IndexableUtil.crashIfContainerIsNullAndThatIsBad(nnull, cntrName_forNullBad);
return null;
}
ArrayList<Object> vo = new ArrayList<Object>(array.length);
for(int i = 0; i < array.length; i++) {
vo.add((Object)array[i]);
}
return vo;
}
*/
/*
<p>Get a {@code java.util.List<String>} containing all elements from a primitive array.</p>
* @param nnull If non-{@code null}, then {@code array} may not be {@code null}. This is used for the potential error message, and <i>should</i> not be empty.
* @return If {@code array} is<ul>
<li>{@code null}: {@code null}</li>
<li>non-{@code null}: A new string-list, containing all elements from {@code array}</li>
</ul>
public static final <E> List<String> getStringListOrNull(E[] array, NullContainer nnull, String cntrName_forNullBad) {
if(array == null) {
IndexableUtil.crashIfContainerIsNullAndThatIsBad(nnull, cntrName_forNullBad);
return null;
}
ArrayList<String> vo = new ArrayList<String>(array.length);
for(int i = 0; i < array.length; i++) {
E o = array[i];
vo.add(((o == null) ? null : o.toString()));
}
return vo;
}
*/
private ArrayUtil() {
throw new IllegalStateException("Do not instantiate");
}
}