Added new Remove/RetainAll function to Collection

This commit is contained in:
Speiger 2021-10-24 01:11:11 +02:00
parent d18a35d9b7
commit b90a9ec7d8
8 changed files with 200 additions and 0 deletions

View File

@ -1,5 +1,8 @@
# Changelog of versions # Changelog of versions
### Version 0.4.5
- Added: removeAll/retainAll(Collection c, Consumer r) which receives all the elements that got deleted from the collection
### Version 0.4.4 ### Version 0.4.4
- Fixed: ObjectArrayList.of was causing crashes because of a Poor implementation. - Fixed: ObjectArrayList.of was causing crashes because of a Poor implementation.
- Added: Unsorted HashMaps/Sets now throw Concurrent exceptions if they were modified during a rehash. - Added: Unsorted HashMaps/Sets now throw Concurrent exceptions if they were modified during a rehash.

View File

@ -3,9 +3,13 @@ package speiger.src.collections.PACKAGE.collections;
import java.util.Collection; import java.util.Collection;
import java.util.Objects; import java.util.Objects;
import java.util.AbstractCollection; import java.util.AbstractCollection;
#if TYPE_OBJECT
import java.util.function.Consumer;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
@ -79,6 +83,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
@Override @Override
public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) { public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) {
Objects.requireNonNull(c); Objects.requireNonNull(c);
if(c.isEmpty()) return true;
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();) for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();)
if(!contains(iter.NEXT())) if(!contains(iter.NEXT()))
return false; return false;
@ -96,6 +101,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
@Primitive @Primitive
public boolean containsAny(Collection<?> c) { public boolean containsAny(Collection<?> c) {
Objects.requireNonNull(c); Objects.requireNonNull(c);
if(c.isEmpty()) return false;
for(Object e : c) for(Object e : c)
if(contains(e)) if(contains(e))
return true; return true;
@ -111,6 +117,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
@Override @Override
public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) { public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) {
Objects.requireNonNull(c); Objects.requireNonNull(c);
if(c.isEmpty()) return false;
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();) for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();)
if(contains(iter.NEXT())) if(contains(iter.NEXT()))
return true; return true;
@ -153,6 +160,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
@Override @Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) {
Objects.requireNonNull(c); Objects.requireNonNull(c);
if(c.isEmpty()) return false;
boolean modified = false; boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
if(c.contains(iter.NEXT())) { if(c.contains(iter.NEXT())) {
@ -163,6 +171,23 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
return modified; return modified;
} }
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
Objects.requireNonNull(c);
if(c.isEmpty()) return false;
Objects.requireNonNull(r);
boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
KEY_TYPE e = iter.NEXT();
if(c.contains(e)) {
r.accept(e);
iter.remove();
modified = true;
}
}
return modified;
}
/** /**
* A Type-Specific implementation of retainAll. This Implementation iterates over all elements and removes them as they were not found in the other collection. * A Type-Specific implementation of retainAll. This Implementation iterates over all elements and removes them as they were not found in the other collection.
* @param c the elements that should be kept * @param c the elements that should be kept
@ -187,6 +212,27 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
return modified; return modified;
} }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
Objects.requireNonNull(c);
Objects.requireNonNull(r);
if(c.isEmpty()) {
boolean modified = !isEmpty();
forEach(r);
clear();
return modified;
}
boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
KEY_TYPE e = iter.NEXT();
if(!c.contains(e)) {
iter.remove();
modified = true;
}
}
return modified;
}
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** /**
* A Type-Specific implementation of toArray that links to {@link #TO_ARRAY(KEY_TYPE[])} with a newly created array. * A Type-Specific implementation of toArray that links to {@link #TO_ARRAY(KEY_TYPE[])} with a newly created array.

View File

@ -8,6 +8,11 @@ import java.util.function.Predicate;
import java.util.stream.JAVA_STREAM; import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
#endif #endif
#if TYPE_OBJECT
import java.util.function.Consumer;
#else
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
@ -115,6 +120,16 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
*/ */
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c); public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c);
/**
* A Type-Specific removeAll function that reduces (un)boxing.
* It also notifies the remover of which exact element is going to be removed.
* @param c the collection of elements that should be removed
* @param r elements that got removed
* @return true if any element was removed
* @see Collection#removeAll(Collection)
*/
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r);
/** /**
* A Type-Specific retainAll function that reduces (un)boxing. * A Type-Specific retainAll function that reduces (un)boxing.
* @param c the collection of elements that should be kept * @param c the collection of elements that should be kept
@ -123,6 +138,16 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
*/ */
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c); public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c);
/**
* A Type-Specific retainAll function that reduces (un)boxing.
* It also notifies the remover of which exact element is going to be removed.
* @param c the collection of elements that should be kept
* @param r elements that got removed
* @return true if any element was removed
* @see Collection#retainAll(Collection)
*/
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r);
/** /**
* A Function that does a shallow clone of the Collection itself. * A Function that does a shallow clone of the Collection itself.
* This function is more optimized then a copy constructor since the Collection does not have to be unsorted/resorted. * This function is more optimized then a copy constructor since the Collection does not have to be unsorted/resorted.

View File

@ -864,6 +864,22 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return modified; return modified;
} }
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
if(c.isEmpty()) return false;
int j = 0;
for(int i = 0;i<size;i++) {
if(!c.contains(data[i])) data[j++] = data[i];
else r.accept(data[i]);
}
boolean modified = j != size;
#if TYPE_OBJECT
Arrays.fill(data, j, size, null);
#endif
size = j;
return modified;
}
/** /**
* A function to retain all elements that were provided in the other collection * A function to retain all elements that were provided in the other collection
* This function might delegate to a more appropriate function if necessary * This function might delegate to a more appropriate function if necessary
@ -891,6 +907,27 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return modified; return modified;
} }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
if(c.isEmpty()) {
boolean modifed = size > 0;
forEach(r);
clear();
return modifed;
}
int j = 0;
for(int i = 0;i<size;i++) {
if(c.contains(data[i])) data[j++] = data[i];
else r.accept(data[i]);
}
boolean modified = j != size;
#if TYPE_OBJECT
Arrays.fill(data, j, size, null);
#endif
size = j;
return modified;
}
#if PRIMITIVES #if PRIMITIVES
/** /**
* A optimized List#removeIf(Predicate) that more quickly removes elements from the list then the ArrayList implementation * A optimized List#removeIf(Predicate) that more quickly removes elements from the list then the ArrayList implementation

View File

@ -370,6 +370,10 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); } public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); } public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) { throw new UnsupportedOperationException(); }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) { throw new UnsupportedOperationException(); }
#if PRIMITIVES #if PRIMITIVES
@Override @Override

View File

@ -714,6 +714,27 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return modified; return modified;
} }
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
if(c.isEmpty()) return false;
boolean modified = false;
int j = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;) {
if(c.contains(entry.value)) {
r.accept(entry.value);
Entry KEY_GENERIC_TYPE next = entry.next;
unlink(entry);
entry = next;
modified = true;
continue;
}
else j++;
entry = entry.next;
}
size = j;
return modified;
}
@Override @Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) {
if(c.isEmpty()) { if(c.isEmpty()) {
@ -738,6 +759,32 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return modified; return modified;
} }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
if(c.isEmpty()) {
boolean changed = size > 0;
forEach(r);
clear();
return changed;
}
boolean modified = false;
int j = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;) {
if(!c.contains(entry.value)) {
r.accept(entry.value);
Entry KEY_GENERIC_TYPE next = entry.next;
unlink(entry);
entry = next;
modified = true;
continue;
}
else j++;
entry = entry.next;
}
size = j;
return modified;
}
@Override @Override
@Primitive @Primitive
public boolean removeIf(Predicate<? super CLASS_TYPE> filter) { public boolean removeIf(Predicate<? super CLASS_TYPE> filter) {

View File

@ -227,6 +227,21 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
return result; return result;
} }
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
int j = 0;
for(int i = 0;i<size;i++) {
if(!c.contains(data[i])) data[j++] = data[i];
else r.accept(data[i]);
}
boolean result = j != size;
#if TYPE_OBJECT
Arrays.fill(data, j, size, null);
#endif
size = j;
return result;
}
@Override @Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) {
int j = 0; int j = 0;
@ -242,6 +257,21 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
return result; return result;
} }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
int j = 0;
for(int i = 0;i<size;i++) {
if(c.contains(data[i])) data[j++] = data[i];
else r.accept(data[i]);
}
boolean result = j != size;
#if TYPE_OBJECT
Arrays.fill(data, j, size, null);
#endif
size = j;
return result;
}
@Override @Override
@Primitive @Primitive
public boolean removeAll(Collection<?> c) { public boolean removeAll(Collection<?> c) {

View File

@ -148,7 +148,11 @@ public class COLLECTIONS
@Override @Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return this.c.removeAll(c); } } public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return this.c.removeAll(c); } }
@Override @Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) { synchronized(mutex) { return this.c.removeAll(c, r); } }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return this.c.retainAll(c); } } public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return this.c.retainAll(c); } }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) { synchronized(mutex) { return this.c.retainAll(c, r); } }
#if PRIMITIVES #if PRIMITIVES
@Override @Override
public boolean remIf(JAVA_PREDICATE filter){ synchronized(mutex) { return c.remIf(filter); } } public boolean remIf(JAVA_PREDICATE filter){ synchronized(mutex) { return c.remIf(filter); } }
@ -258,7 +262,11 @@ public class COLLECTIONS
@Override @Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); } public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) { throw new UnsupportedOperationException(); }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); } public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) { throw new UnsupportedOperationException(); }
#if PRIMITIVES #if PRIMITIVES
@Override @Override
public boolean remIf(JAVA_PREDICATE filter){ throw new UnsupportedOperationException(); } public boolean remIf(JAVA_PREDICATE filter){ throw new UnsupportedOperationException(); }