
com.jongsoft.lang.collection.impl.AbstractSet Maven / Gradle / Ivy
The newest version!
/*
* The MIT License
*
* Copyright 2016-2019 Jong Soft.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.jongsoft.lang.collection.impl;
import static java.lang.String.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import com.jongsoft.lang.API;
import com.jongsoft.lang.collection.*;
import com.jongsoft.lang.collection.support.Collections;
import com.jongsoft.lang.collection.support.PipeCommand;
import com.jongsoft.lang.collection.tuple.Pair;
abstract class AbstractSet implements Set {
private final Object[] delegate;
AbstractSet(Object[] delegate) {
this.delegate = delegate;
}
@Override
public Set append(final T value) {
if (contains(value)) {
return this;
}
Object[] newDelegate = new Object[delegate.length + 1];
System.arraycopy(delegate, 0, newDelegate, 0, delegate.length);
newDelegate[delegate.length] = value;
return this.wrapperSupplier().apply(newDelegate);
}
@Override
@SuppressWarnings("unchecked")
public Set distinctBy(Comparator comparator) {
return com.jongsoft.lang.Collections.Set(comparator, (T[]) delegate);
}
@Override
public List sorted() {
Object[] clone = Arrays.copyOf(delegate, delegate.length);
Arrays.sort(clone);
return new Array<>(clone);
}
@Override
@SuppressWarnings("Duplicates")
public Set remove(final int index) {
validateOutOfBounds(index);
Object[] clone = new Object[delegate.length - 1];
System.arraycopy(delegate, 0, clone, 0, index);
System.arraycopy(delegate, index + 1, clone, index, delegate.length - index - 1);
return this.wrapperSupplier().apply(clone);
}
@Override
public Set replace(int index, T replacement) {
validateOutOfBounds(index);
Object[] clone = new Object[delegate.length];
System.arraycopy(delegate, 0, clone, 0, delegate.length);
clone[index] = replacement;
return this.wrapperSupplier().apply(clone);
}
@Override
@SuppressWarnings("unchecked")
public Set replaceIf(Predicate predicate, T replacement) {
Objects.requireNonNull(predicate, "The predicate cannot be null for this operation.");
Object[] clone = new Object[delegate.length];
System.arraycopy(delegate, 0, clone, 0, delegate.length);
for (int index = 0; index < clone.length; index++) {
if (predicate.test((T) clone[index])) {
clone[index] = replacement;
}
}
return this.wrapperSupplier().apply(clone);
}
@Override
@SuppressWarnings("Duplicates")
public int firstIndexWhere(final Predicate predicate) {
for (int i = 0; i < size(); i++) {
if (predicate.test(get(i))) {
return i;
}
}
return -1;
}
@Override
@SuppressWarnings("unchecked")
public T get(final int index) {
validateOutOfBounds(index);
return (T) delegate[index];
}
@Override
@SuppressWarnings("unchecked")
public Map> groupBy(final Function super T, ? extends K> keyGenerator) {
final Supplier> setSupplier = this.emptySupplier();
return (Map>) Collections.groupBy(setSupplier::get, this, keyGenerator);
}
@Override
public Pair extends Set, ? extends Collection> split(Predicate predicate) {
Map> split = groupBy(predicate::test);
return API.Tuple(split.get(true), split.get(false));
}
@Override
@SuppressWarnings("Duplicates")
public Set tail() {
if (size() == 0) {
throw new NoSuchElementException("Cannot call tail on empty collection");
} else if (size() == 1) {
return this.emptySupplier().get();
}
Object[] tail = new Object[delegate.length - 1];
System.arraycopy(delegate, 1, tail, 0, delegate.length - 1);
return this.wrapperSupplier().apply(tail);
}
@Override
public Set filter(final Predicate predicate) {
return Collections.filter(this.emptySupplier().get(), this, predicate);
}
@Override
@SuppressWarnings("Duplicates")
public Set map(final Function mapper) {
Objects.requireNonNull(mapper, "The mapper cannot be null for this operation.");
Set mappedSet = this.emptySupplier().get();
for (int i = 0; i < size(); i++) {
mappedSet = mappedSet.append(mapper.apply(get(i)));
}
return mappedSet;
}
@Override
public Set orElse(final Iterable extends T> other) {
return isEmpty() ?
this.wrapperSupplier().apply(com.jongsoft.lang.Collections.Iterator(other).toNativeArray())
: this;
}
@Override
public Set orElse(final Supplier extends Iterable extends T>> supplier) {
return isEmpty() ?
this.wrapperSupplier().apply(com.jongsoft.lang.Collections.Iterator(supplier.get()).toNativeArray())
: this;
}
@Override
public Pipeline pipeline() {
return new PipeCommand<>(this);
}
@Override
public int size() {
return delegate.length;
}
@Override
@SuppressWarnings("unchecked")
public Iterator iterator() {
return com.jongsoft.lang.Collections.Iterator((T[]) delegate);
}
@Override
@SuppressWarnings("unchecked")
public java.util.Set toJava() {
java.util.Set result = new java.util.HashSet<>(delegate.length);
for (Object o : delegate) {
result.add((T) o);
}
return result;
}
@Override
public Set union(final Iterable iterable) {
return Collections.>filter(this, iterable, Predicate.not(this::contains));
}
@Override
@SafeVarargs
public final Set intersect(final Iterable...iterable) {
if (iterable.length == 0) {
return this.emptySupplier().get();
}
Predicate operation = com.jongsoft.lang.Collections.Set(iterable)
.map(com.jongsoft.lang.Collections::Set)
.foldLeft(x -> true, (x, xs) -> x.and(xs::contains));
return Collections.filter(this.emptySupplier().get(), this, operation);
}
@Override
@SafeVarargs
public final Set complement(final Iterable...iterables) {
if (iterables.length == 0) {
return this;
}
Predicate operation = com.jongsoft.lang.Collections.Set(iterables)
.map(com.jongsoft.lang.Collections::Set)
.foldLeft(x -> true, (x, xs) -> x.and(Predicate.not(xs::contains)));
return Collections.filter(this.emptySupplier().get(), this, operation);
}
@Override
public String toString() {
return Collections.textValueOf("Set", this);
}
private void validateOutOfBounds(int index) {
if (index >= delegate.length || index < 0) {
throw new IndexOutOfBoundsException(format("%s is not in the bounds of 0 and %s", index, delegate.length));
}
}
protected abstract Supplier> emptySupplier();
protected abstract Function
© 2015 - 2025 Weber Informatics LLC | Privacy Policy