Added Better forEach support for Iterables.

This commit is contained in:
Speiger 2021-10-29 17:23:52 +02:00
parent a25ec85ba2
commit c20c6393e5
2 changed files with 257 additions and 1 deletions

View File

@ -1,8 +1,8 @@
package speiger.src.collections.PACKAGE.collections; package speiger.src.collections.PACKAGE.collections;
import java.util.Objects; import java.util.Objects;
#if !TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.collections.ObjectIterable; import speiger.src.collections.objects.collections.ObjectIterable;
@ -122,6 +122,32 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
return ITERABLES.filter(this, filter); return ITERABLES.filter(this, filter);
} }
/**
* A Helper function to reduce the usage of Streams and allows to filter out duplicated elements
* @return a Iterable that filtered out all duplicated elements
*/
default ITERABLE KEY_GENERIC_TYPE distinct() {
return ITERABLES.distinct(this);
}
/**
* A Helper function to reduce the usage of Streams and allows to limit the amount of elements
* @param limit the amount of elements it should be limited to
* @return a Iterable that is limited in length
*/
default ITERABLE KEY_GENERIC_TYPE limit(long limit) {
return ITERABLES.limit(this, limit);
}
/**
* A Helper function to reduce the usage of Streams and allows to preview elements before they are iterated through
* @param action the action that should be applied
* @return a Peeked Iterable
*/
default ITERABLE KEY_GENERIC_TYPE peek(CONSUMER KEY_GENERIC_TYPE action) {
return ITERABLES.peek(this, action);
}
/** /**
* Helper function to reduce stream usage that allows to filter for any matches. * Helper function to reduce stream usage that allows to filter for any matches.
* @param filter that should be applied * @param filter that should be applied

View File

@ -1,13 +1,25 @@
package speiger.src.collections.PACKAGE.utils; package speiger.src.collections.PACKAGE.utils;
import java.util.Objects;
#if TYPE_BOOLEAN
import java.util.concurrent.atomic.AtomicInteger;
#endif
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import speiger.src.collections.PACKAGE.collections.ITERABLE; import speiger.src.collections.PACKAGE.collections.ITERABLE;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.collections.ObjectIterable; import speiger.src.collections.objects.collections.ObjectIterable;
import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#if !TYPE_BOOLEAN
import speiger.src.collections.PACKAGE.sets.HASH_SET;
import speiger.src.collections.PACKAGE.sets.SET;
#endif
/** /**
* A Helper class for Iterables * A Helper class for Iterables
@ -110,6 +122,70 @@ public class ITERABLES
return new FilteredIterableBRACES(iterable, filter); return new FilteredIterableBRACES(iterable, filter);
} }
/**
* A Helper function that filters out all duplicated elements.
* @param iterable that should be distinct
* @Type(T)
* @return a distinct iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE distinct(ITERABLE KEY_GENERIC_TYPE iterable) {
return new DistinctIterableBRACES(iterable);
}
/**
* A Helper function that filters out all duplicated elements from a Java Iterable.
* @param iterable that should be distinct
* @Type(T)
* @return a distinct iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE distinct(Iterable<? extends CLASS_TYPE> iterable) {
return new DistinctIterableBRACES(wrap(iterable));
}
/**
* A Helper function that hard limits the Iterable to a specific size
* @param iterable that should be limited
* @param limit the amount of elements it should be limited to
* @Type(T)
* @return a limited iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE limit(ITERABLE KEY_GENERIC_TYPE iterable, long limit) {
return new LimitedIterableBRACES(iterable, limit);
}
/**
* A Helper function that hard limits the Iterable to a specific size from a Java Iterable
* @param iterable that should be limited
* @param limit the amount of elements it should be limited to
* @Type(T)
* @return a limited iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE limit(Iterable<? extends CLASS_TYPE> iterable, long limit) {
return new LimitedIterableBRACES(wrap(iterable), limit);
}
/**
* A Helper function that allows to preview the result of a Iterable.
* @param iterable that should be peeked at
* @param action callback that receives the value before the iterable returns it
* @Type(T)
* @return a peeked iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE peek(ITERABLE KEY_GENERIC_TYPE iterable, CONSUMER KEY_GENERIC_TYPE action) {
return new PeekIterableBRACES(iterable, action);
}
/**
* A Helper function that allows to preview the result of a Iterable from a Java Iterable
* @param iterable that should be peeked at
* @param action callback that receives the value before the iterable returns it
* @Type(T)
* @return a peeked iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE peek(Iterable<? extends CLASS_TYPE> iterable, CONSUMER KEY_GENERIC_TYPE action) {
return new PeekIterableBRACES(wrap(iterable), action);
}
/** /**
* A Wrapper function that wraps a Java-Iterable into a Type Specific Iterable * A Wrapper function that wraps a Java-Iterable into a Type Specific Iterable
* @param iterable that should be wrapped * @param iterable that should be wrapped
@ -131,6 +207,19 @@ public class ITERABLES
public ITERATOR KEY_GENERIC_TYPE iterator() { public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.wrap(iterable.iterator()); return ITERATORS.wrap(iterable.iterator());
} }
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterable.forEach(action);
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
iterable.forEach(action);
}
#endif
} }
private static class MappedIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T> private static class MappedIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T>
@ -146,6 +235,12 @@ public class ITERABLES
public ObjectIterator<T> iterator() { public ObjectIterator<T> iterator() {
return ITERATORS.map(iterable.iterator(), mapper); return ITERATORS.map(iterable.iterator(), mapper);
} }
@Override
public void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
iterable.forEach(E -> action.accept(mapper.GET_VALUE(E)));
}
} }
private static class FlatMappedIterable KSS_GENERIC_TYPE<E, T,[SPACE]V extends Iterable<T>> implements ObjectIterable<T> private static class FlatMappedIterable KSS_GENERIC_TYPE<E, T,[SPACE]V extends Iterable<T>> implements ObjectIterable<T>
@ -162,6 +257,13 @@ public class ITERABLES
public ObjectIterator<T> iterator() { public ObjectIterator<T> iterator() {
return ITERATORS.flatMap(iterable.iterator(), mapper); return ITERATORS.flatMap(iterable.iterator(), mapper);
} }
@Override
public void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
iterable.forEach(E -> mapper.GET_VALUE(E).forEach(action));
}
} }
private static class FlatMappedArrayIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T> private static class FlatMappedArrayIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T>
@ -178,6 +280,15 @@ public class ITERABLES
public ObjectIterator<T> iterator() { public ObjectIterator<T> iterator() {
return ITERATORS.arrayFlatMap(iterable.iterator(), mapper); return ITERATORS.arrayFlatMap(iterable.iterator(), mapper);
} }
@Override
public void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
iterable.forEach(E -> {
T[] array = mapper.GET_VALUE(E);
for(int i = 0,m=array.length;i<m;action.accept(array[i++]));
});
}
} }
private static class FilteredIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE private static class FilteredIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE
@ -194,5 +305,124 @@ public class ITERABLES
public ITERATOR KEY_GENERIC_TYPE iterator() { public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.filter(iterable.iterator(), filter); return ITERATORS.filter(iterable.iterator(), filter);
} }
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterable.forEach(T -> { if(!filter.TEST_VALUE(T)) action.accept(T); } );
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
iterable.forEach(T -> { if(!filter.TEST_VALUE(T)) action.accept(T); } );
}
#endif
}
private static class LimitedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE
{
ITERABLE KEY_GENERIC_TYPE iterable;
long limit;
public LimitedIterable(ITERABLE KEY_GENERIC_TYPE iterable, long limit) {
this.iterable = iterable;
this.limit = limit;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.limit(iterable.iterator(), limit);
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
AtomicLong counter = new AtomicLong();
iterable.forEach(T -> {
if(counter.get() >= limit) return;
counter.incrementAndGet();
action.accept(T);
});
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
AtomicLong counter = new AtomicLong();
iterable.forEach(T -> {
if(counter.get() >= limit) return;
counter.incrementAndGet();
action.accept(T);
});
}
#endif
}
private static class DistinctIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE
{
ITERABLE KEY_GENERIC_TYPE iterable;
public DistinctIterable(ITERABLE KEY_GENERIC_TYPE iterable) {
this.iterable = iterable;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.distinct(iterable.iterator());
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
#if TYPE_BOOLEAN
AtomicInteger result = new AtomicInteger();
iterable.forEach(T -> {
if(((result.get() & (T ? 2 : 1)) != 0)) return;
result.getAndAdd(T ? 2 : 1);
action.accept(T);
});
#else
SET KEY_GENERIC_TYPE filtered = new HASH_SETBRACES();
iterable.forEach(T -> { if(filtered.add(T)) action.accept(T); });
#endif
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
SET KEY_GENERIC_TYPE filtered = new HASH_SETBRACES();
iterable.forEach(T -> { if(filtered.add(T)) action.accept(T); });
}
#endif
}
private static class PeekIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE
{
ITERABLE KEY_GENERIC_TYPE iterable;
CONSUMER KEY_GENERIC_TYPE action;
public PeekIterable(ITERABLE KEY_GENERIC_TYPE iterable, CONSUMER KEY_GENERIC_TYPE action) {
this.iterable = iterable;
this.action = action;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.peek(iterable.iterator(), action);
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterable.forEach(this.action.andThen(action));
}
#else
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
iterable.forEach(this.action.andThen(action));
}
#endif
} }
} }