ValueIterator returns the right type

This commit is contained in:
Shautvast 2023-05-26 18:32:13 +02:00
parent 578600c3ae
commit 1241c64d3e
2 changed files with 34 additions and 12 deletions

View file

@ -214,14 +214,8 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
* <p> * <p>
* Because the values differ in type the output type is Object * Because the values differ in type the output type is Object
* <p> * <p>
* NB the actual type (right now) is the `raw` value: all integers are of type Long, BigInteger is String
* // That is unfortunate (or must I say: annoying!), but for something like JSON not a problem (I think).
* // So maybe keep this in (say 'rawValueIterator') and also create a typesafe iterator.
* <p>
* It detects {@link ConcurrentModificationException} if the underlying list was updated while iterating. * It detects {@link ConcurrentModificationException} if the underlying list was updated while iterating.
* <p> * <p>
* // I should probably include a type so that the caller could cast to the correct type
* // not sure yet
* *
* @return an Iterator<?> * @return an Iterator<?>
*/ */
@ -230,8 +224,7 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
} }
/** /**
* Returns a list of the types that are in the data * @return a list of types in the Object(graph). So the element type and all (nested) properties
* @return
*/ */
public List<Class<?>> getTypes() { public List<Class<?>> getTypes() {
final List<Class<?>> types = new ArrayList<>(); final List<Class<?>> types = new ArrayList<>();
@ -239,6 +232,7 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
return types; return types;
} }
private void getTypes(TypeHandler handler, List<Class<?>> types) { private void getTypes(TypeHandler handler, List<Class<?>> types) {
if (handler instanceof BuiltinTypeHandler<?>) { if (handler instanceof BuiltinTypeHandler<?>) {
types.add(handler.getType()); types.add(handler.getType());
@ -249,11 +243,30 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
} }
} }
List<BuiltinTypeHandler<?>> getBuiltinTypeHandlers() {
final List<BuiltinTypeHandler<?>> types = new ArrayList<>();
getStoredTypes(rootHandler, types);
return types;
}
private void getStoredTypes(TypeHandler handler, List<BuiltinTypeHandler<?>> types) {
if (handler instanceof BuiltinTypeHandler<?>) {
types.add((BuiltinTypeHandler<?>) handler);
} else {
((CompoundTypeHandler) handler).getProperties()
.forEach(propertyHandler -> getStoredTypes(propertyHandler, types));
}
}
public class ValueIterator implements Iterator<Object> { public class ValueIterator implements Iterator<Object> {
private final int originalSize; private final int originalSize;
private final int originalPosition; private final int originalPosition;
private final List<BuiltinTypeHandler<?>> typeHandlers;
private Iterator<BuiltinTypeHandler<?>> typeHandlersIterator;
ValueIterator() { ValueIterator() {
typeHandlers = getBuiltinTypeHandlers();
typeHandlersIterator = typeHandlers.iterator();
this.originalSize = size; this.originalSize = size;
this.originalPosition = data.position(); this.originalPosition = data.position();
data.position(0); data.position(0);
@ -273,7 +286,16 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
* so that's why we first check for modifications (me and the computer) * so that's why we first check for modifications (me and the computer)
* *
* I could also maintain the position here. But you main want to fail ... dunno */ * I could also maintain the position here. But you main want to fail ... dunno */
return ValueReader.read(data); Object rawValue = ValueReader.read(data);
// transform (currently integers to the expected type)
BuiltinTypeHandler<?> handler;
while (!typeHandlersIterator.hasNext()) {
typeHandlersIterator = typeHandlers.iterator();
}
handler = typeHandlersIterator.next();
return handler.transform(rawValue);
} }
} }

View file

@ -168,7 +168,7 @@ public class ContiguousListTest {
} }
long prevValue = -1; long prevValue = -1;
for (Iterator<?> intIter = integers.valueIterator(); intIter.hasNext(); ) { for (Iterator<?> intIter = integers.valueIterator(); intIter.hasNext(); ) {
long value = (long) intIter.next(); int value = (int) intIter.next();
assertEquals(prevValue, value - 1); assertEquals(prevValue, value - 1);
prevValue = value; prevValue = value;
} }
@ -187,7 +187,7 @@ public class ContiguousListTest {
} }
long prevValue = -1; long prevValue = -1;
for (Iterator<?> intIter = integers.valueIterator(); intIter.hasNext(); ) { for (Iterator<?> intIter = integers.valueIterator(); intIter.hasNext(); ) {
long value = (long) intIter.next(); // here a value (IntBean.value) int value = (int) intIter.next();
assertEquals(prevValue, value - 1); assertEquals(prevValue, value - 1);
prevValue = value; prevValue = value;
} }
@ -199,7 +199,7 @@ public class ContiguousListTest {
} }
@Test @Test
public void testGetStoredTypesWhenCompound() { public void testGetTypesWhenCompound() {
ContiguousList<NestedBean> integers = new ContiguousList<>(NestedBean.class); ContiguousList<NestedBean> integers = new ContiguousList<>(NestedBean.class);
Iterator<Class<?>> typeIterator = integers.getTypes().iterator(); Iterator<Class<?>> typeIterator = integers.getTypes().iterator();
assertTrue(typeIterator.hasNext()); assertTrue(typeIterator.hasNext());