forked from Speiger/Primitive-Collections
New Content patch getting big progress on base and progress on lists.
-Changed: Build Task no longer Sync's because it is 9x slower and a File Builder never collides with another File Builder. -Added: getEquals() function for faster compare builders. -Changed: getNonClassType to getNonFileType() -Added: New Rule to the Rule Sheet. -Added: Regex Helper so recursion is supported -Added: FunctionMapper that supports more then 1 argument. -Changed: Injection & FunctionMapper support recursion- -Added: Loads of Variables to the GlobalVariables as they were added for templates. -Added: AbstractCollection, AbstractList, List, ListIterator, BidirectionalIterator, Arrays and ArrayList template.
This commit is contained in:
parent
c61c8a7806
commit
5cc4f35407
|
@ -12,5 +12,6 @@ Some Base Rules:
|
|||
- Function overloads should be avoided. They are only causing problems.
|
||||
- If a primitive function would cause a overload then a rename should try to add a shortened primitive name in it. If that destroys the naming flow then a cut version name. If that does not work a new rule has to be made up. Example: "get -> getInt" while "removeIf => removeIfInt" does not work so we default to "removeIf => remIf".
|
||||
- If a function would break the java interface rules (ArrayList.trimToSize) a dedicated interface should be created for it.
|
||||
- If a #if is wrapping a function the #if always starts after a empty new line and the #endif always has a empty new line before itself. That way empty lines match up no matter the type
|
||||
|
||||
Rules can be added or altered, but should only be so if there is a real reason to be present.
|
|
@ -37,9 +37,9 @@ public enum ClassType
|
|||
return classType;
|
||||
}
|
||||
|
||||
public String getNonClassType()
|
||||
public String getNonFileType()
|
||||
{
|
||||
return this == OBJECT ? "" : classType;
|
||||
return this == OBJECT ? "" : fileType;
|
||||
}
|
||||
|
||||
public String getFileType()
|
||||
|
@ -67,6 +67,17 @@ public enum ClassType
|
|||
return this == BYTE || this == SHORT || this == CHAR || this == FLOAT;
|
||||
}
|
||||
|
||||
public String getEquals()
|
||||
{
|
||||
switch(this)
|
||||
{
|
||||
case DOUBLE: return "Double.doubleToLongBits(%1$s) == Double.doubleToLongBits(%2$s)";
|
||||
case FLOAT: return "Float.floatToIntBits(%1$s) == Float.floatToIntBits(%2$s)";
|
||||
case OBJECT: return "Objects.equals(%1$s, %2$s)";
|
||||
default: return "%1$s == %2$s";
|
||||
}
|
||||
}
|
||||
|
||||
public ClassType getCustomJDKType()
|
||||
{
|
||||
switch(this)
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import speiger.src.builder.mappers.ArgumentMapper;
|
||||
import speiger.src.builder.mappers.InjectMapper;
|
||||
import speiger.src.builder.mappers.SimpleMapper;
|
||||
import speiger.src.builder.processor.TemplateProcess;
|
||||
|
@ -28,15 +29,23 @@ public class GlobalVariables
|
|||
addSimpleMapper("CLASS_TYPE", type.getClassType());
|
||||
addSimpleMapper("KEY_TYPE", type.getKeyType());
|
||||
addSimpleMapper(" KEY_GENERIC_TYPE", type == ClassType.OBJECT ? "<"+type.getKeyType()+">" : "");
|
||||
addSimpleMapper(" GENERIC_BRACES", type == ClassType.OBJECT ? " <"+type.getKeyType()+">" : "");
|
||||
addSimpleMapper("BRACES", type == ClassType.OBJECT ? "<>" : "");
|
||||
if(type.needsCustomJDKType())
|
||||
{
|
||||
addSimpleMapper("JAVA_TYPE", type.getCustomJDKType().getKeyType());
|
||||
addSimpleMapper("SANITY_CAST", "castTo"+type.getFileType());
|
||||
}
|
||||
addSimpleMapper("KEY_TO_OBJ", type.getClassType()+".valueOf");
|
||||
addInjectMapper("OBJ_TO_KEY(\\([^)]+\\)|\\S)", "%s."+type.getKeyType()+"Value()").removeBraces();
|
||||
addInjectMapper("CLASS_TO_KEY(\\([^)]+\\)|\\S)", "(("+type.getClassType()+")%s)."+type.getKeyType()+"Value()").removeBraces();
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalVariables createHelperVariables()
|
||||
{
|
||||
addArgumentMapper("EQUALS_KEY_TYPE", type == ClassType.OBJECT ? "Objects.equals(%1$s, %2$s)" : "Objects.equals(KEY_TO_OBJ(%1$s), %2$s)").removeBraces();
|
||||
addArgumentMapper("EQUALS", type.getEquals()).removeBraces();
|
||||
addSimpleMapper("KEY_TO_OBJ", type.getClassType()+".valueOf");
|
||||
addInjectMapper("OBJ_TO_KEY", type == ClassType.OBJECT ? "%s" : "%s."+type.getKeyType()+"Value()").removeBraces();
|
||||
addInjectMapper("CLASS_TO_KEY", "(("+type.getClassType()+")%s)."+type.getKeyType()+"Value()").removeBraces();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -44,17 +53,31 @@ public class GlobalVariables
|
|||
{
|
||||
addSimpleMapper("JAVA_PREDICATE", type.isPrimitiveBlocking() ? "" : type.getCustomJDKType().getFileType()+"Predicate");
|
||||
addSimpleMapper("JAVA_CONSUMER", type.isPrimitiveBlocking() ? "" : "java.util.function."+type.getCustomJDKType().getFileType()+"Consumer");
|
||||
addSimpleMapper("CONSUMER", type.getFileType()+"Consumer");
|
||||
addSimpleMapper("ITERATOR", type.getFileType()+"Iterator");
|
||||
addSimpleMapper("ITERABLE", type.getFileType()+"Iterable");
|
||||
addSimpleMapper("ABSTRACT_COLLECTION", type.getFileType()+"AbstractCollection");
|
||||
addSimpleMapper("COLLECTION", type.getFileType()+"Collection");
|
||||
addClassMapper("CONSUMER", "Consumer");
|
||||
addClassMapper("ITERATORS", "Iterators");
|
||||
addClassMapper("BI_ITERATOR", "BidirectionalIterator");
|
||||
addClassMapper("LIST_ITERATOR", "ListIterator");
|
||||
addClassMapper("ITERATOR", "Iterator");
|
||||
addClassMapper("ITERABLE", "Iterable");
|
||||
addClassMapper("ABSTRACT_COLLECTION", "AbstractCollection");
|
||||
addClassMapper("COLLECTION", "Collection");
|
||||
addClassMapper("ARRAYS", "Arrays");
|
||||
addClassMapper("ABSTRACT_LIST", "AbstractList");
|
||||
addClassMapper("LIST_ITER", "ListIter");
|
||||
addClassMapper("SUB_LIST", "SubList");
|
||||
addClassMapper("ARRAY_LIST", "ArrayList");
|
||||
addClassMapper("LIST", "List");
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalVariables createFunctions()
|
||||
{
|
||||
addSimpleMapper("NEXT()", "next"+type.getNonClassType()+"()");
|
||||
addFunctionMapper("NEXT", "next");
|
||||
addSimpleMapper("TO_ARRAY", "to"+type.getNonFileType()+"Array");
|
||||
addFunctionMapper("GET_KEY", "get");
|
||||
addFunctionMapper("REMOVE_KEY", "rem");
|
||||
addFunctionMapper("REMOVE", "remove");
|
||||
addFunctionMapper("PREVIOUS", "previous");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -86,6 +109,16 @@ public class GlobalVariables
|
|||
return type;
|
||||
}
|
||||
|
||||
private void addClassMapper(String pattern, String replacement)
|
||||
{
|
||||
operators.add(new SimpleMapper(pattern, type.getFileType()+replacement));
|
||||
}
|
||||
|
||||
private void addFunctionMapper(String pattern, String replacement)
|
||||
{
|
||||
operators.add(new SimpleMapper(pattern, replacement+type.getNonFileType()));
|
||||
}
|
||||
|
||||
private void addSimpleMapper(String pattern, String replacement)
|
||||
{
|
||||
operators.add(new SimpleMapper(pattern, replacement));
|
||||
|
@ -98,6 +131,18 @@ public class GlobalVariables
|
|||
return mapper;
|
||||
}
|
||||
|
||||
private ArgumentMapper addArgumentMapper(String pattern, String replacement)
|
||||
{
|
||||
return addArgumentMapper(pattern, replacement, ", ");
|
||||
}
|
||||
|
||||
private ArgumentMapper addArgumentMapper(String pattern, String replacement, String splitter)
|
||||
{
|
||||
ArgumentMapper mapper = new ArgumentMapper(pattern, replacement, splitter);
|
||||
operators.add(mapper);
|
||||
return mapper;
|
||||
}
|
||||
|
||||
class PathBuilder implements UnaryOperator<Path>
|
||||
{
|
||||
String before;
|
||||
|
|
|
@ -45,6 +45,7 @@ public class TestBuilder extends TemplateProcessor
|
|||
{
|
||||
GlobalVariables type = new GlobalVariables(clzType);
|
||||
type.createFlags();
|
||||
type.createHelperVariables();
|
||||
type.createVariables();
|
||||
type.createClassTypes();
|
||||
type.createFunctions();
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package speiger.src.builder.mappers;
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import speiger.src.builder.misc.RegexUtil;
|
||||
|
||||
public class ArgumentMapper implements UnaryOperator<String>
|
||||
{
|
||||
Pattern pattern;
|
||||
String replacement;
|
||||
String argumentBreaker;
|
||||
String braces = "()";
|
||||
boolean removeBraces;
|
||||
|
||||
public ArgumentMapper(String pattern, String replacement, String argumentBreaker)
|
||||
{
|
||||
this.pattern = Pattern.compile(pattern);
|
||||
this.replacement = replacement;
|
||||
this.argumentBreaker = argumentBreaker;
|
||||
}
|
||||
|
||||
public ArgumentMapper setBraceType(String s)
|
||||
{
|
||||
if(s.length() != 2) throw new IllegalStateException("Start and End char only");
|
||||
braces = s;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArgumentMapper removeBraces()
|
||||
{
|
||||
removeBraces = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(String t)
|
||||
{
|
||||
Matcher matcher = pattern.matcher(t);
|
||||
if(matcher.find())
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
do
|
||||
{
|
||||
String text = RegexUtil.searchUntil(t, matcher.end()-1, braces.charAt(0), braces.charAt(1));
|
||||
if(!text.isEmpty())
|
||||
{
|
||||
RegexUtil.skip(matcher.appendReplacement(buffer, ""), text.length());
|
||||
buffer.append(String.format(replacement, (Object[])getString(text).split(argumentBreaker)));
|
||||
}
|
||||
}
|
||||
while(matcher.find());
|
||||
matcher.appendTail(buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
protected String getString(String s)
|
||||
{
|
||||
return removeBraces ? s.substring(1, s.length() - 1) : s;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,10 +4,13 @@ import java.util.function.UnaryOperator;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import speiger.src.builder.misc.RegexUtil;
|
||||
|
||||
public class InjectMapper implements UnaryOperator<String>
|
||||
{
|
||||
Pattern pattern;
|
||||
String replacement;
|
||||
String braces = "()";
|
||||
boolean removeBraces;
|
||||
|
||||
public InjectMapper(String pattern, String replacement)
|
||||
|
@ -16,6 +19,13 @@ public class InjectMapper implements UnaryOperator<String>
|
|||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
public InjectMapper setBraceType(String s)
|
||||
{
|
||||
if(s.length() != 2) throw new IllegalStateException("Start and End char only");
|
||||
braces = s;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InjectMapper removeBraces()
|
||||
{
|
||||
removeBraces = true;
|
||||
|
@ -29,7 +39,14 @@ public class InjectMapper implements UnaryOperator<String>
|
|||
if(matcher.find())
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
do { matcher.appendReplacement(buffer, String.format(replacement, getString(matcher.group(1))));
|
||||
do
|
||||
{
|
||||
String text = RegexUtil.searchUntil(t, matcher.end()-1, braces.charAt(0), braces.charAt(1));
|
||||
if(!text.isEmpty())
|
||||
{
|
||||
RegexUtil.skip(matcher.appendReplacement(buffer, ""), text.length());
|
||||
buffer.append(String.format(replacement, getString(text)));
|
||||
}
|
||||
} while (matcher.find());
|
||||
matcher.appendTail(buffer);
|
||||
return buffer.toString();
|
||||
|
@ -37,7 +54,7 @@ public class InjectMapper implements UnaryOperator<String>
|
|||
return t;
|
||||
}
|
||||
|
||||
private String getString(String s)
|
||||
protected String getString(String s)
|
||||
{
|
||||
return removeBraces ? s.substring(1, s.length() - 1) : s;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package speiger.src.builder.misc;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public class RegexUtil
|
||||
{
|
||||
static Field LAST_POS;
|
||||
|
||||
public static Matcher skip(Matcher matcher, int amount)
|
||||
{
|
||||
try
|
||||
{
|
||||
LAST_POS.setInt(matcher, LAST_POS.getInt(matcher) + amount);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return matcher;
|
||||
}
|
||||
|
||||
public static String searchUntil(String text, int startIndex, char increase, char decrease)
|
||||
{
|
||||
if(text.charAt(startIndex + 1) != increase)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
int inc = 0;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for(int i = startIndex + 1;i<text.length();i++)
|
||||
{
|
||||
char current = text.charAt(i);
|
||||
if(current == '\\' && i < text.length() - 1 && text.charAt(i+1) == 'n')
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else if(current == increase)
|
||||
{
|
||||
inc++;
|
||||
}
|
||||
else if(current == decrease)
|
||||
{
|
||||
inc--;
|
||||
if(inc <= 0)
|
||||
{
|
||||
return builder.append(decrease).toString();
|
||||
}
|
||||
}
|
||||
builder.append(current);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
Field field = Matcher.class.getDeclaredField("lastAppendPosition");
|
||||
field.setAccessible(true);
|
||||
LAST_POS = field;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ public class BuildTask implements Runnable
|
|||
catch(Exception e)
|
||||
{
|
||||
}
|
||||
try(BufferedWriter writer = Files.newBufferedWriter(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE, StandardOpenOption.SYNC))
|
||||
try(BufferedWriter writer = Files.newBufferedWriter(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE))
|
||||
{
|
||||
writer.write(s);
|
||||
writer.flush();
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package speiger.src.collections.utils;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public interface BidirectionalIterator<E> extends Iterator<E>
|
||||
{
|
||||
public E previous();
|
||||
|
||||
public boolean hasPrevious();
|
||||
|
||||
public default int back(int amount) {
|
||||
if(amount < 0) throw new IllegalStateException("Can't go forward");
|
||||
int i = 0;
|
||||
for(;i<amount && hasPrevious();previous(),i++);
|
||||
return i;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,12 @@
|
|||
package speiger.src.collections.PACKAGE.collections;
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
import java.util.Collection;
|
||||
#endif
|
||||
import java.util.AbstractCollection;
|
||||
#if !TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.utils.ITERATORS;
|
||||
#endif
|
||||
|
||||
public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractCollection<CLASS_TYPE> implements COLLECTION KEY_GENERIC_TYPE
|
||||
{
|
||||
|
@ -31,6 +37,30 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c)
|
||||
{
|
||||
return c instanceof COLLECTION ? containsAll((COLLECTION)c) : super.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends CLASS_TYPE> c)
|
||||
{
|
||||
return c instanceof COLLECTION ? addAll((COLLECTION)c) : super.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c)
|
||||
{
|
||||
return c instanceof COLLECTION ? removeAll((COLLECTION)c) : super.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c)
|
||||
{
|
||||
return c instanceof COLLECTION ? retainAll((COLLECTION)c) : super.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(COLLECTION c) {
|
||||
for(KEY_TYPE e : c)
|
||||
|
@ -51,6 +81,17 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
|
|||
@Deprecated
|
||||
public boolean remove(Object e) { return COLLECTION.super.remove(e); }
|
||||
|
||||
@Override
|
||||
public boolean REMOVE_KEY(KEY_TYPE e) {
|
||||
for(ITERATOR iter = iterator();iter.hasNext();) {
|
||||
if(EQUALS(iter.NEXT(), e)) {
|
||||
iter.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(COLLECTION c) {
|
||||
boolean modified = false;
|
||||
|
@ -74,5 +115,15 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
|
|||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
public KEY_TYPE[] TO_ARRAY() {
|
||||
return TO_ARRAY(new KEY_TYPE[size()]);
|
||||
}
|
||||
|
||||
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
|
||||
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
|
||||
ITERATORS.unwrap(a, iterator());
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package speiger.src.collections.PACKAGE.collections;
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
|
||||
|
||||
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, ObjectBidirectionalIterator<CLASS_TYPE>
|
||||
#else
|
||||
import speiger.src.collections.utils.BidirectionalIterator;
|
||||
|
||||
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, BidirectionalIterator<CLASS_TYPE>
|
||||
#endif
|
||||
{
|
||||
public KEY_TYPE PREVIOUS();
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
@Deprecated
|
||||
public default CLASS_TYPE previous() {
|
||||
return KEY_TO_OBJ(PREVIOUS());
|
||||
}
|
||||
|
||||
@Override
|
||||
default int skip(int amount)
|
||||
{
|
||||
return ITERATOR.super.skip(amount);
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -19,7 +19,7 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
|
|||
|
||||
public boolean containsAny(COLLECTION c);
|
||||
|
||||
public boolean remove(KEY_TYPE o);
|
||||
public boolean REMOVE_KEY(KEY_TYPE o);
|
||||
|
||||
public boolean removeAll(COLLECTION c);
|
||||
|
||||
|
@ -56,14 +56,6 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
|
|||
@Deprecated
|
||||
public default boolean remove(Object o) { return o != null && remove(CLASS_TO_KEY(o)); }
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public <K> K[] toArray(K[] a);
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Object[] toArray();
|
||||
|
||||
#endif
|
||||
@Override
|
||||
public ITERATOR KEY_GENERIC_TYPE iterator();
|
||||
|
|
|
@ -16,7 +16,7 @@ public interface ITERATOR KEY_GENERIC_TYPE extends Iterator<CLASS_TYPE>
|
|||
|
||||
@Deprecated
|
||||
@Override
|
||||
public default CLASS_TYPE next() { return KEY_TO_OBJ(next()); }
|
||||
public default CLASS_TYPE next() { return KEY_TO_OBJ(NEXT()); }
|
||||
|
||||
public default void forEachRemaining(CONSUMER action) {
|
||||
Objects.requireNonNull(action);
|
||||
|
@ -33,8 +33,8 @@ public interface ITERATOR KEY_GENERIC_TYPE extends Iterator<CLASS_TYPE>
|
|||
#endif
|
||||
default int skip(int amount) {
|
||||
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
||||
int temp = amount;
|
||||
for(;amount > 0 && hasNext();NEXT(), amount--);
|
||||
return temp - amount;
|
||||
int i = 0;
|
||||
for(;i<amount && hasNext();NEXT(), i++);
|
||||
return i;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,296 @@
|
|||
package speiger.src.collections.PACKAGE.lists;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
|
||||
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
|
||||
#if !TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.collections.COLLECTION;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
||||
|
||||
public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
|
||||
{
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
public boolean add(KEY_TYPE e) {
|
||||
add(size(), e);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(COLLECTION c) {
|
||||
boolean modified = false;
|
||||
for(KEY_TYPE e : c)
|
||||
modified |= add(e);
|
||||
return modified;
|
||||
}
|
||||
|
||||
#endif
|
||||
@Override
|
||||
public boolean addAll(LIST KEY_GENERIC_TYPE c) {
|
||||
boolean modified = false;
|
||||
for(KEY_TYPE e : c)
|
||||
modified |= add(e);
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
|
||||
#if TYPE_OBJECT
|
||||
if(o == null) {
|
||||
while(iter.hasNext()) {
|
||||
if(iter.NEXT() == null)
|
||||
return iter.previousIndex();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if(o == null) return -1;
|
||||
#endif
|
||||
while(iter.hasNext()) {
|
||||
if(EQUALS_KEY_TYPE(iter.NEXT(), o))
|
||||
return iter.previousIndex();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator(size());
|
||||
#if TYPE_OBJECT
|
||||
if(o == null) {
|
||||
while(iter.hasPrevious()) {
|
||||
if(iter.PREVIOUS() == null)
|
||||
return iter.nextIndex();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if(o == null) return -1;
|
||||
#endif
|
||||
while(iter.hasPrevious()) {
|
||||
if(EQUALS_KEY_TYPE(iter.PREVIOUS(), o))
|
||||
return iter.nextIndex();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
public int indexOf(KEY_TYPE e) {
|
||||
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
|
||||
while(iter.hasNext()) {
|
||||
if(EQUALS(iter.NEXT(), e))
|
||||
return iter.previousIndex();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(KEY_TYPE e) {
|
||||
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator(size());
|
||||
while(iter.hasPrevious()) {
|
||||
if(EQUALS(iter.PREVIOUS(), e))
|
||||
return iter.nextIndex();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@Override
|
||||
public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) {
|
||||
return new SUB_LIST(this, fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITERATOR KEY_GENERIC_TYPE iterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
|
||||
return new LIST_ITER(index);
|
||||
}
|
||||
|
||||
private class SUB_LIST extends ABSTRACT_LIST KEY_GENERIC_TYPE {
|
||||
ABSTRACT_LIST KEY_GENERIC_TYPE l;
|
||||
int offset;
|
||||
int size;
|
||||
|
||||
SUB_LIST(ABSTRACT_LIST KEY_GENERIC_TYPE l, int from, int to) {
|
||||
if (from < 0) throw new IndexOutOfBoundsException("fromIndex = " + from);
|
||||
else if (to > l.size()) throw new IndexOutOfBoundsException("toIndex = " + to);
|
||||
else if (from > to) throw new IllegalArgumentException("fromIndex(" + from + ") > toIndex(" + to + ")");
|
||||
this.l = l;
|
||||
offset = from;
|
||||
size = to - from;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, KEY_TYPE e) {
|
||||
checkAddRange(index);
|
||||
l.add(index+offset, e);
|
||||
size++;
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
public void add(int index, CLASS_TYPE element) {
|
||||
add(index, OBJ_TO_KEY(element));
|
||||
}
|
||||
|
||||
#endif
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
|
||||
checkAddRange(index);
|
||||
int size = c.size();
|
||||
if(size == 0) return false;
|
||||
l.addAll(index + offset, l);
|
||||
offset += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
|
||||
checkAddRange(index);
|
||||
int size = c.size();
|
||||
if(size == 0) return false;
|
||||
l.addAll(index + offset, l);
|
||||
offset += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@Override
|
||||
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
|
||||
checkAddRange(index);
|
||||
int size = c.size();
|
||||
if(size == 0) return false;
|
||||
l.addAll(index + offset, l);
|
||||
offset += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE GET_KEY(int index) {
|
||||
checkRange(index);
|
||||
return l.GET_KEY(index + offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE set(int index, KEY_TYPE e) {
|
||||
checkRange(index);
|
||||
return l.set(index + offset, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE REMOVE(int index) {
|
||||
checkRange(index);
|
||||
size--;
|
||||
return l.REMOVE(index + offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
private void checkRange(int index) {
|
||||
if (index < 0 || index >= size)
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
|
||||
}
|
||||
|
||||
private void checkAddRange(int index) {
|
||||
if (index < 0 || index > size)
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
|
||||
}
|
||||
}
|
||||
|
||||
private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE {
|
||||
int index;
|
||||
int lastReturned = -1;
|
||||
|
||||
LIST_ITER(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return index < size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE NEXT() {
|
||||
return GET_KEY(index++);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE PREVIOUS() {
|
||||
return GET_KEY(index--);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return index-1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if(lastReturned == -1)
|
||||
throw new IllegalStateException();
|
||||
ABSTRACT_LIST.this.REMOVE(lastReturned);
|
||||
if(lastReturned < index)
|
||||
index--;
|
||||
lastReturned = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(KEY_TYPE e) {
|
||||
if(lastReturned == -1)
|
||||
throw new IllegalStateException();
|
||||
ABSTRACT_LIST.this.set(lastReturned, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(KEY_TYPE e) {
|
||||
if(lastReturned == -1)
|
||||
throw new IllegalStateException();
|
||||
ABSTRACT_LIST.this.add(index++, e);
|
||||
lastReturned = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int skip(int amount) {
|
||||
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
||||
int steps = Math.min(amount, (size() - 1) - index);
|
||||
index += steps;
|
||||
return steps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int back(int amount) {
|
||||
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
||||
int steps = Math.min(amount, index);
|
||||
index -= steps;
|
||||
return steps;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
package speiger.src.collections.PACKAGE.lists;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.collections.COLLECTION;
|
||||
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
||||
#endif
|
||||
|
||||
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
||||
{
|
||||
transient KEY_TYPE[] data;
|
||||
private int size = 0;
|
||||
|
||||
public ARRAY_LIST(int size)
|
||||
{
|
||||
#if TYPE_OBJECT
|
||||
data = (KEY_TYPE[])new Object[size];
|
||||
#else
|
||||
data = new KEY_TYPE[size];
|
||||
#endif
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, CLASS_TYPE element)
|
||||
{
|
||||
checkAddRange(index);
|
||||
ensureCapacity(size + 1);
|
||||
if(index != size) System.arraycopy(data, index, data, index+1, size - index);
|
||||
data[index] = OBJ_TO_KEY(element);
|
||||
size++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(KEY_TYPE e)
|
||||
{
|
||||
ensureCapacity(size + 1);
|
||||
data[size++] = e;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
public void add(int index, KEY_TYPE e)
|
||||
{
|
||||
checkAddRange(index);
|
||||
ensureCapacity(size + 1);
|
||||
if(index != size) System.arraycopy(data, index, data, index+1, size - index);
|
||||
data[index] = e;
|
||||
size++;
|
||||
}
|
||||
|
||||
#endif
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c)
|
||||
{
|
||||
#if !TYPE_OBJECT
|
||||
if(c instanceof COLLECTION) return addAll((COLLECTION)c);
|
||||
#endif
|
||||
int add = c.size();
|
||||
if(add <= 0) return false;
|
||||
ensureCapacity(size + add);
|
||||
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
|
||||
size+=add;
|
||||
Iterator<? extends CLASS_TYPE> iter = c.iterator();
|
||||
while(add != 0) data[index++] = OBJ_TO_KEY(iter.next());
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c)
|
||||
{
|
||||
if(c instanceof LIST) return addAll((LIST)c);
|
||||
int add = c.size();
|
||||
if(add <= 0) return false;
|
||||
ensureCapacity(size + add);
|
||||
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
|
||||
size+=add;
|
||||
ITERATOR KEY_GENERIC_TYPE iter = c.iterator();
|
||||
while(add != 0) data[index++] = iter.NEXT();
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE GET_KEY(int index)
|
||||
{
|
||||
if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")");
|
||||
return data[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE set(int index, KEY_TYPE e)
|
||||
{
|
||||
if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")");
|
||||
KEY_TYPE old = data[index];
|
||||
data[index] = e;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE REMOVE(int index)
|
||||
{
|
||||
if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")");
|
||||
KEY_TYPE old = data[index];
|
||||
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
||||
#if TYPE_OBJECT
|
||||
data[size] = null;
|
||||
#endif
|
||||
size--;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
#if TYPE_OBJECT
|
||||
for(int i = 0;i<size;data[i] = null,i++);
|
||||
#endif
|
||||
size = 0;
|
||||
}
|
||||
|
||||
protected void ensureCapacity(int capacity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void checkAddRange(int index)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package speiger.src.collections.PACKAGE.lists;
|
||||
|
||||
import java.util.List;
|
||||
import speiger.src.collections.PACKAGE.collections.COLLECTION;
|
||||
|
||||
public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List<CLASS_TYPE>
|
||||
{
|
||||
#if !TYPE_OBJECT
|
||||
public boolean add(KEY_TYPE e);
|
||||
|
||||
public void add(int index, KEY_TYPE e);
|
||||
|
||||
public boolean addAll(int index, COLLECTION c);
|
||||
|
||||
#endif
|
||||
public boolean addAll(LIST KEY_GENERIC_TYPE c);
|
||||
|
||||
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c);
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
public KEY_TYPE GET_KEY(int index);
|
||||
|
||||
public KEY_TYPE set(int index, KEY_TYPE e);
|
||||
|
||||
public KEY_TYPE REMOVE(int index);
|
||||
|
||||
public int indexOf(KEY_TYPE e);
|
||||
|
||||
public int lastIndexOf(KEY_TYPE e);
|
||||
|
||||
#endif
|
||||
@Override
|
||||
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator();
|
||||
|
||||
@Override
|
||||
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index);
|
||||
|
||||
@Override
|
||||
public LIST KEY_GENERIC_TYPE subList(int from, int to);
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
@Deprecated
|
||||
public default boolean add(CLASS_TYPE e) {
|
||||
return COLLECTION.super.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default CLASS_TYPE get(int index) {
|
||||
return KEY_TO_OBJ(GET_KEY(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default CLASS_TYPE set(int index, CLASS_TYPE e) {
|
||||
return KEY_TO_OBJ(set(index, OBJ_TO_KEY(e)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default int indexOf(Object o) {
|
||||
return indexOf(CLASS_TO_KEY(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default int lastIndexOf(Object o) {
|
||||
return indexOf(CLASS_TO_KEY(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default boolean contains(Object o) {
|
||||
return COLLECTION.super.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default boolean remove(Object o) {
|
||||
return COLLECTION.super.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default CLASS_TYPE remove(int index) {
|
||||
return KEY_TO_OBJ(REMOVE(index));
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package speiger.src.collections.PACKAGE.lists;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
|
||||
|
||||
public interface LIST_ITERATOR KEY_GENERIC_TYPE extends ListIterator<CLASS_TYPE>, BI_ITERATOR KEY_GENERIC_TYPE
|
||||
{
|
||||
#if !TYPE_OBJECT
|
||||
public void set(KEY_TYPE e);
|
||||
|
||||
public void add(KEY_TYPE e);
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default CLASS_TYPE previous() {
|
||||
return BI_ITERATOR.super.previous();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default CLASS_TYPE next() {
|
||||
return BI_ITERATOR.super.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default void set(CLASS_TYPE e) {
|
||||
set(OBJ_TO_KEY(e));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public default void add(CLASS_TYPE e) {
|
||||
add(OBJ_TO_KEY(e));
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package speiger.src.collections.PACKAGE.utils;
|
||||
|
||||
public class ARRAYS
|
||||
{
|
||||
#if !TYPE_OBJECT
|
||||
public static CLASS_TYPE[] wrap(KEY_TYPE[] a) {
|
||||
CLASS_TYPE[] result = new CLASS_TYPE[a.length];
|
||||
for(int i = 0,m=a.length;i<m;i++)
|
||||
result[i] = KEY_TO_OBJ(a[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static KEY_TYPE[] unwrap(CLASS_TYPE[] a) {
|
||||
KEY_TYPE[] result = new KEY_TYPE[a.length];
|
||||
for(int i = 0,m=a.length;i<m;i++)
|
||||
result[i] = OBJ_TO_KEY(a[i]);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package speiger.src.collections.PACKAGE.utils;
|
||||
|
||||
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
||||
|
||||
public class ITERATORS
|
||||
{
|
||||
public static GENERIC_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE[] a) {
|
||||
return wrap(a, 0, a.length);
|
||||
}
|
||||
|
||||
public static GENERIC_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE[] a, int start, int end) {
|
||||
return new ArrayIteratorBRACES(a, start, end);
|
||||
}
|
||||
|
||||
public static GENERIC_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i) {
|
||||
return unwrap(a, i, 0, a.length);
|
||||
}
|
||||
|
||||
public static GENERIC_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset) {
|
||||
return unwrap(a, i, offset, a.length);
|
||||
}
|
||||
|
||||
public static GENERIC_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset, int max) {
|
||||
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
|
||||
if(offset + max >= a.length) throw new IllegalStateException("largest array index exceeds array size");
|
||||
int index = 0;
|
||||
for(;index<max && i.hasNext();index++) a[index+offset] = i.NEXT();
|
||||
return index;
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
public static GENERIC_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i) {
|
||||
return unwrap(a, i, 0, a.length);
|
||||
}
|
||||
|
||||
public static GENERIC_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset) {
|
||||
return unwrap(a, i, offset, a.length);
|
||||
}
|
||||
|
||||
public static GENERIC_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset, int max) {
|
||||
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
|
||||
if(offset + max >= a.length) throw new IllegalStateException("largest array index exceeds array size");
|
||||
int index = 0;
|
||||
for(;index<max && i.hasNext();index++) a[index+offset] = KEY_TO_OBJ(i.NEXT());
|
||||
return index;
|
||||
}
|
||||
|
||||
#endif
|
||||
private static class ArrayIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
|
||||
{
|
||||
KEY_TYPE[] a;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
ArrayIterator(KEY_TYPE[] a, int from, int to) {
|
||||
this.a = a;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return from < to;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE NEXT() {
|
||||
return a[from++];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int skip(int amount) {
|
||||
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
||||
int left = Math.min(amount, to - from);
|
||||
from += left;
|
||||
return amount - left;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue