com.rapiddweller.common.ArrayUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rd-lib-common Show documentation
Show all versions of rd-lib-common Show documentation
'rapiddweller Common' is an open source Java library
forked from Databene Commons by Volker Bergmann.
It provides extensions to the Java core library by utility classes, abstract concepts
and concrete implementations.
/*
* Copyright (C) 2004-2015 Volker Bergmann ([email protected]).
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.rapiddweller.common;
import com.rapiddweller.common.iterator.ArrayIterator;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
/**
* Provides array-related operations.
* Created: 09.06.2006 21:31:49
*
* @author Volker Bergmann
* @since 0.1
*/
public final class ArrayUtil {
/**
* Binary search int.
*
* @param the type parameter
* @param array the array
* @param item the item
* @param comparator the comparator
* @param resultIfNotFound the result if not found
* @return the int
*/
public static int binarySearch(T[] array, T item, Comparator comparator, UnfoundResult resultIfNotFound) {
int index = Arrays.binarySearch(array, item, comparator);
if (index >= 0) {
return index;
} else {
switch (resultIfNotFound) {
case PREV:
return -index - 2;
case NEXT:
return -index - 1;
case NEG:
return -1;
default:
throw new UnsupportedOperationException("Not a supported option: " + resultIfNotFound);
}
}
}
/**
* Copy of range t [ ].
*
* @param the type parameter
* @param array the array
* @param offset the offset
* @param length the length
* @return the t [ ]
*/
public static T[] copyOfRange(T[] array, int offset, int length) {
return copyOfRange(array, offset, length, componentType(array));
}
/**
* Component type class.
*
* @param the type parameter
* @param array the array
* @return the class
*/
@SuppressWarnings("unchecked")
public static Class componentType(T[] array) {
Class resultType = (Class) array.getClass();
return (Class) resultType.getComponentType();
}
/**
* Copy of range t [ ].
*
* @param the type parameter
* @param array the array
* @param offset the offset
* @param length the length
* @param componentType the component type
* @return the t [ ]
*/
@SuppressWarnings("unchecked")
public static T[] copyOfRange(Object[] array, int offset, int length, Class componentType) {
T[] result = (T[]) Array.newInstance(componentType, length);
System.arraycopy(array, offset, result, 0, length);
return result;
}
/**
* Sub array string [ ].
*
* @param array the array
* @param offset the offset
* @return the string [ ]
*/
public static String[] subArray(String[] array, int offset) {
String[] result = new String[array.length - offset];
System.arraycopy(array, offset, result, 0, array.length - offset);
return result;
}
/**
* Remove element t [ ].
*
* @param the type parameter
* @param item the item
* @param array the array
* @return the t [ ]
*/
public static T[] removeElement(T item, T[] array) {
int index = indexOf(item, array);
return remove(index, array);
}
/**
* Remove t [ ].
*
* @param the type parameter
* @param indexToRemove the index to remove
* @param array the array
* @return the t [ ]
*/
@SuppressWarnings("unchecked")
public static T[] remove(int indexToRemove, T[] array) {
Class componentType = componentType(array);
T[] result = (T[]) Array.newInstance(componentType, array.length - 1);
if (indexToRemove > 0) {
System.arraycopy(array, 0, result, 0, indexToRemove);
}
System.arraycopy(array, indexToRemove + 1, result, indexToRemove, array.length - indexToRemove - 1);
return result;
}
/**
* Remove all t [ ].
*
* @param the type parameter
* @param toRemove the to remove
* @param target the target
* @return the t [ ]
*/
public static T[] removeAll(T[] toRemove, T[] target) {
Class componentType = componentType(target);
ArrayBuilder builder = new ArrayBuilder<>(componentType);
for (T element : target) {
if (!contains(element, toRemove)) {
builder.add(element);
}
}
return builder.toArray();
}
// containment check -----------------------------------------------------------------------------------------------
/**
* Tells if an array contains a specific element
*
* @param element the element to search
* @param array the array to scan
* @return true if the element was found, else false
*/
public static boolean contains(Object element, Object array) {
int length = Array.getLength(array);
for (int i = 0; i < length; i++) {
Object o = Array.get(array, i);
if (NullSafeComparator.equals(o, element)) {
return true;
}
}
return false;
}
/**
* Contains all boolean.
*
* @param the type parameter
* @param subArray the sub array
* @param superArray the super array
* @return the boolean
*/
public static boolean containsAll(T[] subArray, T[] superArray) {
for (T t : subArray) {
if (!contains(t, superArray)) {
return false;
}
}
return true;
}
/**
* Index of int.
*
* @param subArray the sub array
* @param array the array
* @return the int
*/
public static int indexOf(byte[] subArray, byte[] array) {
return indexOf(subArray, 0, array);
}
/**
* Index of int.
*
* @param subArray the sub array
* @param fromIndex the from index
* @param array the array
* @return the int
*/
public static int indexOf(byte[] subArray, int fromIndex, byte[] array) {
for (int i = fromIndex; i <= array.length - subArray.length; i++) {
boolean match = true;
for (int j = 0; j < subArray.length; j++) {
if (array[i + j] != subArray[j]) {
match = false;
}
}
if (match) {
return i;
}
}
return -1;
}
/**
* Ends with sequence boolean.
*
* @param the type parameter
* @param candidates the candidates
* @param searched the searched
* @return the boolean
*/
public static boolean endsWithSequence(T[] candidates, T[] searched) {
if (searched.length > candidates.length) {
return false;
}
for (int i = 0; i < searched.length; i++) {
if (!candidates[candidates.length - searched.length + i].equals(searched[i])) {
return false;
}
}
return true;
}
/**
* Common elements t [ ].
*
* @param the type parameter
* @param sources the sources
* @return the t [ ]
*/
@SuppressWarnings("unchecked")
public static T[] commonElements(T[]... sources) {
Class componentType = null;
for (int arrayNumber = 0; arrayNumber < sources.length && componentType == null; arrayNumber++) {
T[] source = sources[arrayNumber];
for (int index = 0; index < source.length && componentType == null; index++) {
if (source[index] != null) {
componentType = (Class) source[index].getClass();
}
}
}
return commonElements(componentType, sources);
}
/**
* Common elements t [ ].
*
* @param the type parameter
* @param componentType the component type
* @param sources the sources
* @return the t [ ]
*/
@SafeVarargs
public static T[] commonElements(Class componentType, T[]... sources) {
ArrayBuilder builder = new ArrayBuilder<>(componentType);
T[] firstArray = sources[0];
for (T element : firstArray) {
boolean common = true;
for (int i = 1; i < sources.length; i++) {
if (!ArrayUtil.contains(element, sources[i])) {
common = false;
break;
}
}
if (common) {
builder.add(element);
}
}
return builder.toArray();
}
// identity checks -------------------------------------------------------------------------------------------------
/**
* Equals ignore order boolean.
*
* @param the type parameter
* @param a1 the a 1
* @param a2 the a 2
* @return the boolean
*/
public static boolean equalsIgnoreOrder(T[] a1, T[] a2) {
if (a1 == a2) {
return true;
}
if (a1 == null) {
return false;
}
if (a1.length != a2.length) {
return false;
}
List l1 = new ArrayList<>(a1.length);
Collections.addAll(l1, a1);
for (int i = a1.length - 1; i >= 0; i--) {
if (contains(a1[i], a2)) {
l1.remove(i);
} else {
return false;
}
}
return l1.size() == 0;
}
/**
* Equals boolean.
*
* @param a1 the a 1
* @param a2 the a 2
* @return the boolean
*/
public static boolean equals(Object a1, Object a2) {
if (a1 == a2) {
return true;
}
if (a1 == null || !(a1.getClass().isArray()) || !(a2.getClass().isArray())) {
return false;
}
int length = Array.getLength(a1);
if (length != Array.getLength(a2)) {
return false;
}
List