completed PrimitiveList implementation
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
package dev.asdf00.general.utils.list;
|
||||
|
||||
import dev.asdf00.general.utils.list.internal.ByteList;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static dev.asdf00.general.utils.list.internal.ListReader.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TestList {
|
||||
|
||||
@Test
|
||||
public void basicByteTest() {
|
||||
var list = PrimitiveList.create(Byte.class);
|
||||
list.add((byte) 3);
|
||||
list.addByte((byte) 4);
|
||||
assertListStats(list, 2, 2, 8);
|
||||
|
||||
var array = createByteArray(14);
|
||||
list.addAll(1, toBoxedBytes(array));
|
||||
assertListStats(list, 16, 3, 16);
|
||||
assertEquals("last element", 4, list.getByte(15));
|
||||
assertEquals("first element", Byte.valueOf((byte) 3), list.get(0));
|
||||
|
||||
list.add(1, (byte) 11);
|
||||
assertListStats(list, 17, 4, 32);
|
||||
|
||||
list.remove(Byte.valueOf((byte) 3));
|
||||
assertListStats(list, 16, 5, 32);
|
||||
assertEquals("first element", 11, list.getByte(0));
|
||||
|
||||
assertThrows(ConcurrentModificationException.class, () -> {
|
||||
for (Byte b : list) {
|
||||
list.remove(b);
|
||||
}
|
||||
});
|
||||
list.remove(14);
|
||||
assertListStats(list, 14, 7, 32);
|
||||
assertArrayEquals("toArray", toBoxedBytes(array).toArray(Byte[]::new), list.toArray(Byte[]::new));
|
||||
assertArrayEquals("finalizeAsArray", array, list.finalizeAsByteArray());
|
||||
assertTrue("isFinalized", list.isFinalized());
|
||||
assertThrows(NullPointerException.class, () -> list.lastIndexOf(12));
|
||||
assertThrows(NullPointerException.class, () -> list.get(0));
|
||||
assertThrows(NullPointerException.class, () -> list.finalizeAsByteArray());
|
||||
assertThrows(UnsupportedOperationException.class, () -> list.toBooleanArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indexOutOfBoundsByte() {
|
||||
assertThrows(IllegalArgumentException.class, () -> PrimitiveList.create(Object.class));
|
||||
|
||||
var list = PrimitiveList.create(Byte.class);
|
||||
assertTrue("empty", list.isEmpty());
|
||||
assertEquals("size", 0, list.size());
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> list.getByte(-1));
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> list.getByte(0));
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> list.get(0));
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> list.add(-1, Byte.valueOf((byte) 1)));
|
||||
list.add((byte) 2);
|
||||
list.add((byte) 2);
|
||||
assertThrows(IllegalArgumentException.class, () -> list.subList(1, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subListTestByte() {
|
||||
var a0 = new byte[]{0, 1, 1, 1, 0, 0};
|
||||
var list = PrimitiveList.create(Byte.class);
|
||||
list.addAll(toBoxedBytes(a0));
|
||||
List<Byte> subList = list.subList(3, 6);
|
||||
subList.remove(0);
|
||||
assertListStats(list, 5, 2, 8);
|
||||
assertArrayEquals("data", new byte[]{0, 1, 1, 0, 0}, list.toByteArray());
|
||||
|
||||
subList.add((byte) 1);
|
||||
assertListStats(list, 6, 3, 8);
|
||||
assertArrayEquals("data", new byte[]{0, 1, 1, 0, 0, 1}, list.toByteArray());
|
||||
|
||||
subList = list.subList(2, 2);
|
||||
assertTrue("subList empty", subList.isEmpty());
|
||||
subList.add((byte) 2);
|
||||
assertListStats(list, 7, 4, 8);
|
||||
assertArrayEquals("data", new byte[]{0, 1, 2, 1, 0, 0, 1}, list.toByteArray());
|
||||
|
||||
subList.clear();
|
||||
assertListStats(list, 6, 5, 8);
|
||||
assertArrayEquals("data", new byte[]{0, 1, 1, 0, 0, 1}, list.toByteArray());
|
||||
|
||||
list.add(3, (byte) 2);
|
||||
subList = list.subList(1, 5);
|
||||
subList.removeAll(List.of((byte) 1, (byte) 2));
|
||||
assertListStats(list, 4, 9, 8);
|
||||
assertArrayEquals("data", new byte[]{0, 0, 0, 1}, list.toByteArray());
|
||||
|
||||
list.addAll(List.of((byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 3));
|
||||
final List<Byte> finalSubList = subList;
|
||||
assertThrows(ConcurrentModificationException.class, () -> finalSubList.get(0));
|
||||
assertListStats(list, 9, 10, 16);
|
||||
assertArrayEquals("data", new byte[]{0, 0, 0, 1, 0, 1, 0, 2, 3}, list.toByteArray());
|
||||
|
||||
list.retainAll(List.of((byte) 1, (byte) 2));
|
||||
assertListStats(list, 3, 16, 16);
|
||||
assertArrayEquals("data", new byte[]{1, 1, 2}, list.toByteArray());
|
||||
|
||||
list.clear();
|
||||
assertListStats(list, 0, 17, 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void assertListStats(PrimitiveList<?> list, int size, int modCnt, int length) {
|
||||
assertEquals("size", size, getSize(list));
|
||||
assertEquals("modCnt", modCnt, getModCnt(list));
|
||||
assertEquals("length", length, getLength(list));
|
||||
}
|
||||
|
||||
public static final Random seedRng = new Random(42);
|
||||
|
||||
public static byte[] createByteArray(int len) {
|
||||
return createByteArray(len, seedRng.nextInt());
|
||||
}
|
||||
|
||||
public static byte[] createByteArray(int len, int seed) {
|
||||
Random rng = new Random(seed);
|
||||
var array = new byte[len];
|
||||
for (int i = 0; i < len; array[i++] = (byte) rng.nextInt());
|
||||
return array;
|
||||
}
|
||||
|
||||
public static Collection<Byte> toBoxedBytes(byte[] array) {
|
||||
var result = new ArrayList<Byte>(array.length);
|
||||
for (byte b : array) {
|
||||
result.add(b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package dev.asdf00.general.utils.list.internal;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class ListReader {
|
||||
public static int getSize(AbstractBaseList list) {
|
||||
return list.size;
|
||||
}
|
||||
|
||||
public static int getModCnt(AbstractBaseList list) {
|
||||
return list.modCnt;
|
||||
}
|
||||
|
||||
public static int getLength(AbstractBaseList list) {
|
||||
try {
|
||||
Class<?> cls = list.getClass();
|
||||
Field data = cls.getDeclaredField("data");
|
||||
if (!data.canAccess(list)) {
|
||||
data.setAccessible(true);
|
||||
}
|
||||
Object array = data.get(list);
|
||||
if (array == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return AbstractBaseList.UNSAFE.getInt(array, AbstractBaseList.OFFSET_LEN);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user