Commit a45f20c2 authored by Thomas Fjellstrom's avatar Thomas Fjellstrom

add ArraySet and some utility functions

parent 0dd48b12
Pipeline #544 passed with stages
in 5 minutes and 31 seconds
package ca.bulltech.util;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public
......@@ -8,13 +10,16 @@ class ArrayUtil
public static
<T>
boolean contains(final T[] array, final T obj)
boolean contains(@NotNull final T[] array, final T obj)
{
for (final T item: array)
if (obj != null)
{
if (Objects.equals(item, obj))
for (final T item : array)
{
return true;
if (Objects.equals(item, obj))
{
return true;
}
}
}
......
package ca.bulltech.util;
import ca.bulltech.util.collect.ArraySet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Iterator;
import javax.annotation.Nullable;
import java.util.List;
import java.util.ListIterator;
/**
* Created by Thomas Fjellstrom on 15/05/18.
*/
public final class CollectionUtil
public final
class CollectionUtil
{
private CollectionUtil() {}
@Nullable
public static <T> T getArrayElement(T[] arr, int idx)
public static
<T> T getArrayElement(@NotNull T[] arr, int idx)
{
if (idx < 0 || idx > arr.length)
{
......@@ -24,12 +28,23 @@ public final class CollectionUtil
}
@Nullable
public static <T> T getArrayElement(Collection<T> arr, int idx)
public static
<T> T getArrayElement(@NotNull Collection<T> arr, int idx)
{
T item = null;
if (arr instanceof List)
{
return ((List<T>)arr).get(idx);
}
if (arr instanceof ArraySet)
{
return ((ArraySet<T>)arr).get(idx);
}
Iterator<T> iterator = arr.iterator();
for(int i = 0; i <= idx; i++)
for (int i = 0; i <= idx; i++)
{
if (!iterator.hasNext())
{
......@@ -43,6 +58,26 @@ public final class CollectionUtil
return item;
}
@Nullable
public static
<T> T getLastElement(@NotNull final Collection<T> arr)
{
if (arr instanceof List)
{
return getLastElement((List<T>)arr);
}
Iterator<T> iterator = arr.iterator();
T item = null;
while (iterator.hasNext())
{
item = iterator.next();
}
return item;
}
/*@Nullable
public static <T> T getLastElement(T[] arr)
{
......@@ -54,17 +89,27 @@ public final class CollectionUtil
return checkArrayElement(arr, arr.length-1);
}*/
@Nullable
public static <T> T getLastElement(final Collection<T> arr)
@NotNull
public static
<T> ListIterator<T> reverseIterator(@NotNull final List<T> list)
{
Iterator<T> iterator = arr.iterator();
T item = null;
return list.listIterator(list.size());
}
while (iterator.hasNext())
{
item = iterator.next();
}
@Nullable
public static
<T> T getLastElement(@NotNull final ListIterator<T> it)
{
return it.hasPrevious() ? it.previous() : null;
}
return item;
@Nullable
public static
<T> T getLastElement(@NotNull final List<T> list)
{
return getLastElement(reverseIterator(list));
}
private
CollectionUtil() {}
}
......@@ -24,6 +24,7 @@ package ca.bulltech.util;
import java.util.Collection;
import ca.bulltech.util.collect.ArraySet;
import ca.bulltech.util.collect.ImmutableList;
/**
......@@ -49,4 +50,10 @@ class Collections
{
return ImmutableList.of(t);
}
public static
<T> ArraySet<T> arraySetOf(final T... items)
{
return new ArraySet<>(items);
}
}
......@@ -46,7 +46,7 @@ class Preconditions
@CanIgnoreReturnValue
@Contract(value = "!null, _ -> !null; null, _ -> fail", pure = true)
public static
<T> T checkNotNull(@Nullable final T obj, final @PrintFormat String message)
<T> T checkNotNull(@Nullable final T obj, final String message)
{
if (obj != null)
{
......@@ -223,5 +223,18 @@ class Preconditions
return value;
}
public static <T>
void assertEquals(@NotNull final T[] expected, @NotNull final T[] actual)
{
if (expected == actual)
{
return;
}
assert expected.length == actual.length : "expected and actual length differ";
for (int i = 0; i < expected.length; i++)
{
assert expected[i].equals(actual[i]) : String.format("item at %d not equal. expected %s. actual %s", i, expected[i], actual[i]);
}
}
}
package ca.bulltech.util.collect;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import static ca.bulltech.util.Preconditions.checkPositionIndex;
public abstract
class AbstractIndexedListIterator<T> implements ListIterator<T>
{
protected final int mSize;
protected int mPosition;
public
AbstractIndexedListIterator(int size)
{
this(size, 0);
}
public
AbstractIndexedListIterator(int size, int position)
{
checkPositionIndex(size, position);
mSize = size;
mPosition = position;
}
protected abstract
T get(int index);
@Override
public
boolean hasNext()
{
return mPosition < mSize;
}
@Override
public
T next()
{
if (hasNext())
{
return get(mPosition++);
}
throw new NoSuchElementException();
}
@Override
public
boolean hasPrevious()
{
return mPosition > 0;
}
@Override
public
T previous()
{
if (hasPrevious())
{
return get(--mPosition);
}
throw new NoSuchElementException();
}
@Override
public
int nextIndex()
{
return mPosition;
}
@Override
public
int previousIndex()
{
return mPosition - 1;
}
@Override
@Deprecated
public final
void remove()
{
throw new UnsupportedOperationException();
}
@Override
@Deprecated
public final
void add(final T t)
{
throw new UnsupportedOperationException();
}
}
package ca.bulltech.util.collect;
import org.jetbrains.annotations.NotNull;
import static ca.bulltech.util.Preconditions.checkElementIndex;
import static ca.bulltech.util.Preconditions.checkNotNull;
public
class ArrayIterator<T> extends AbstractIndexedListIterator<T>
{
private final T[] mData;
private final int mOffset;
public ArrayIterator(@NotNull T[] array, int offset, int length, int position)
{
super(length, position);
mData = checkNotNull(array, "Null array?!");
mOffset = offset;
}
@Override
protected
T get(final int index)
{
return mData[mOffset + index];
}
@Override
public
void set(final T t)
{
checkElementIndex(mOffset + mPosition, mSize);
mData[mOffset + mPosition] = t;
}
}
This diff is collapsed.
......@@ -34,6 +34,9 @@ import java.lang.reflect.Array;
public
class Arrays
{
public static final int[] EMPTY_INT_ARRAY = new int[0];
public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
static
<T> T[] newArray(T[] reference, int length)
{
......
package ca.bulltech.util.collect;
class ContainerHelpers
{
// This is Arrays.binarySearch(), but doesn't do any argument validation.
static
int binarySearch(int[] array, int size, int value)
{
int lo = 0;
int hi = size - 1;
while (lo <= hi)
{
final int mid = (lo + hi) >>> 1;
final int midVal = array[mid];
if (midVal < value)
{
lo = mid + 1;
}
else if (midVal > value)
{
hi = mid - 1;
}
else
{
return mid; // value found
}
}
return ~lo; // value not present
}
static
int binarySearch(long[] array, int size, long value)
{
int lo = 0;
int hi = size - 1;
while (lo <= hi)
{
final int mid = (lo + hi) >>> 1;
final long midVal = array[mid];
if (midVal < value)
{
lo = mid + 1;
}
else if (midVal > value)
{
hi = mid - 1;
}
else
{
return mid; // value found
}
}
return ~lo; // value not present
}
}
package ca.bulltech.util.log;
import ca.bulltech.util.ArrayUtil;
import ca.bulltech.util.ClassUtil;
import ca.bulltech.util.annotation.NonNull;
import com.google.common.base.Splitter;
import com.google.common.collect.Streams;
import org.intellij.lang.annotations.PrintFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.StreamSupport;
/**
* Created by Thomas Fjellstrom on 20/05/18.
*/
public class LogFormat
public
class LogFormat
{
//private static final
//Logger LOG = LoggerFactory.getLogger(LogFormat.class);
......@@ -25,16 +25,6 @@ public class LogFormat
private static
ArrayList<String> stackTraceClassIgnore = null;
private static void initIgnore()
{
if (stackTraceClassIgnore == null)
{
stackTraceClassIgnore = new ArrayList<>();
stackTraceClassIgnore.add("ca.bulltech.util.log.");
stackTraceClassIgnore.add("java.");
}
}
public static
void ignoreStackTraceClass(@NonNull String className)
{
......@@ -43,19 +33,22 @@ public class LogFormat
}
@NonNull
public static String format(int idx, final String message)
public static
String format(int idx, final String message)
{
return format(null, idx, message, false);
}
@NonNull
public static String formatWithBreadcrumbs(int idx, final String message)
public static
String formatWithBreadcrumbs(int idx, final String message)
{
return format(null, idx, message, true);
}
@NonNull
public static String format(Throwable t, int idx, final String message, boolean addBreadcrumbs)
public static
String format(Throwable t, int idx, final String message, boolean addBreadcrumbs)
{
StackTraceElement[] stackTrace = getStackTrace(idx, t);
......@@ -71,15 +64,15 @@ public class LogFormat
}
else
{
String sunJavaCommand = System.getProperty("sun.java.command");
Iterable<String> args2 = Splitter.on(Pattern.compile("\\s+")).trimResults().split(sunJavaCommand);
Optional<String> cmd = StreamSupport.stream(args2.spliterator(), false).findFirst();
String sunJavaCommand = System.getProperty("sun.java.command");
Iterable<String> args2 = Splitter.on(Pattern.compile("\\s+")).trimResults().split(sunJavaCommand);
Optional<String> cmd = StreamSupport.stream(args2.spliterator(), false).findFirst();
simpleName = ClassUtil.simpleName(cmd.orElse("<unkown>"));
}
}
else
{
simpleName = !addBreadcrumbs ? "" : getBreadcrumbs(stackTrace, 0);
simpleName = getBreadcrumbs(stackTrace, 0);
}
return String.format(
......@@ -88,24 +81,35 @@ public class LogFormat
traceElement != null ? traceElement.getMethodName() : "<unk>", message);
}
public static String format(final String message)
public static
String format(final String message)
{
return format(null, 0, message, false);
}
public static String format(final @PrintFormat String format, final Object... args)
public static
String format(final @PrintFormat String format, final Object... args)
{
return format(String.format(format, args));
}
@NonNull
public static String format(int idx, final @PrintFormat String format, final Object... args)
public static
String format(int idx, final @PrintFormat String format, final Object... args)
{
return format(idx, String.format(format, args));
}
@NonNull
public static StackTraceElement[] getStackTrace(int startIdx, @Nullable Throwable t)
public static
String format(final Throwable t, int idx, final @PrintFormat String format, final Object... args)
{
return format(t, idx, String.format(format, args), false);
}
@NonNull
public static
StackTraceElement[] getStackTrace(int startIdx, @Nullable Throwable t)
{
StackTraceElement[] originalStackTrace = null;
......@@ -119,14 +123,15 @@ public class LogFormat
}
int internalStartIdx = 0;
for(int i = 0; i < originalStackTrace.length; i++)
for (int i = 0; i < originalStackTrace.length; i++)
{
if (shouldIgnoreClassName(originalStackTrace[i].getClassName()))
{
//LOG.info("getStackTrace: ignore " + originalStackTrace[i].getClassName() + "." + originalStackTrace[i].getMethodName());
internalStartIdx++;
}
else {
else
{
//LOG.info("getStackTrace: ignore break at " + originalStackTrace[i].getClassName() + "." + originalStackTrace[i].getMethodName());
// once we hit a non skippable class, break out
// so we don't skip past things we care about.
......@@ -134,43 +139,24 @@ public class LogFormat
}
}
return Arrays.copyOfRange(originalStackTrace, internalStartIdx+startIdx, originalStackTrace.length-1);
}
private static
boolean shouldIgnoreClassName(@NonNull String className)
{
//LOG.info("shouldIgnoreClassName: check " + className);
initIgnore();
for (int j = 0; j < stackTraceClassIgnore.size(); j++)
{
String ignorePrefix = stackTraceClassIgnore.get(j);
//LOG.info("shouldIgnoreClassName: check against " + ignorePrefix);
if (className.startsWith(ignorePrefix))
{
//LOG.info("shouldIgnoreClassName: " + className);
return true;
}
}
return false;
return Arrays.copyOfRange(originalStackTrace, internalStartIdx + startIdx, originalStackTrace.length - 1);
}
@NonNull
public static StackTraceElement[] getStackTrace(int startIdx)
public static
StackTraceElement[] getStackTrace(int startIdx)
{
StackTraceElement[] originalStackTrace = Thread.currentThread().getStackTrace();
return Arrays.copyOfRange(originalStackTrace, startIdx+1, originalStackTrace.length-1);
return Arrays.copyOfRange(originalStackTrace, startIdx + 1, originalStackTrace.length - 1);
}
@NonNull
public static String getBreadcrumbs(@NonNull StackTraceElement[] stackTrace, int startIdx)
public static
String getBreadcrumbs(@NonNull StackTraceElement[] stackTrace, int startIdx)
{
StringBuilder sb = new StringBuilder();
for (int i = stackTrace.length-1; i >= startIdx; i--)
for (int i = stackTrace.length - 1; i >= startIdx; i--)
{
StackTraceElement element = stackTrace[i];
String className = ClassUtil.compressedSimpleName(element.getClassName());
......@@ -185,5 +171,37 @@ public class LogFormat
return sb.toString();
}
private static
void initIgnore()
{
if (stackTraceClassIgnore == null)
{
stackTraceClassIgnore = new ArrayList<>();
stackTraceClassIgnore.add("ca.bulltech.util.log.");
stackTraceClassIgnore.add("java.");
}
}
private static
boolean shouldIgnoreClassName(@NonNull String className)
{
//LOG.info("shouldIgnoreClassName: check " + className);
initIgnore();
for (int j = 0; j < stackTraceClassIgnore.size(); j++)
{
String ignorePrefix = stackTraceClassIgnore.get(j);
//LOG.info("shouldIgnoreClassName: check against " + ignorePrefix);
if (className.startsWith(ignorePrefix))
{
//LOG.info("shouldIgnoreClassName: " + className);
return true;
}
}
return false;
}
}
package ca.bulltech.util;
import ca.bulltech.util.collect.ArraySet;
import ca.bulltech.util.log.Logger;
import com.google.common.collect.Lists;
import org.junit.jupiter.api.Test;
import java.util.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class CollectionUtilTest
{
private static final Logger LOG = Logger.getInstance(CollectionUtilTest.class);
@Test
void testGetArrayElementArray()
{
final Integer[] array = { 1, 2, 3, 4, 5 };
for (int i = 0; i < array.length; i++)
{
assertEquals(array[i], CollectionUtil.getArrayElement(array, i));
}
}
@Test
void testGetArrayElementCollection()
{
final List<Integer> orig = Arrays.asList(1, 2, 3, 4);
final Collection<Integer> listCollection = orig;
final Iterator<Integer> listIt = listCollection.iterator();
for (int i = 0; i < listCollection.size(); i++)
{
assertEquals(listIt.next(), CollectionUtil.getArrayElement(listCollection, i));
}
final Collection<Integer> setCollection = new ArraySet<>(orig);
final Iterator<Integer> setIt = setCollection.iterator();
for (int i = 0; i < setCollection.size(); i++)
{
assertEquals(setIt.next(), CollectionUtil.getArrayElement(setCollection, i));
}
final Collection<Integer> hashCollection = new HashSet<>(orig);
assertEquals(orig.size(), hashCollection.size());
assertTrue(orig.containsAll(hashCollection));
}
// TODO: finish writing tests
// @Test
// void testGetLastElementCollection()
// {
// }
//
// @Test
// void reverseIterator()
// {
// }
//
// @Test
// void testGetLastElement()
// {
// }
//
// @Test
// void testGetLastElement1()