
com.github.tonivade.purefun.data.ImmutableArray Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of purefun-core Show documentation
Show all versions of purefun-core Show documentation
Functional Programming Library for Java
The newest version!
/*
* Copyright (c) 2018-2024, Antonio Gabriel Muñoz Conejo
* Distributed under the terms of the MIT License
*/
package com.github.tonivade.purefun.data;
import static com.github.tonivade.purefun.core.Precondition.checkNonNull;
import static java.util.stream.Collectors.collectingAndThen;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.pcollections.PVector;
import org.pcollections.TreePVector;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.core.Equal;
import com.github.tonivade.purefun.core.Function1;
import com.github.tonivade.purefun.core.Matcher1;
/**
* Similar to a ArrayList
* @param the type of elements in this array
*/
public interface ImmutableArray extends Sequence {
List toList();
@Override
ImmutableArray append(E element);
@Override
ImmutableArray remove(E element);
@Override
ImmutableArray appendAll(Sequence extends E> other);
@Override
ImmutableArray removeAll(Sequence extends E> other);
@Override
ImmutableArray reverse();
ImmutableArray sort(Comparator super E> comparator);
E get(int position);
ImmutableArray remove(int position);
ImmutableArray replace(int position, E element);
ImmutableArray insert(int position, E element);
ImmutableArray insertAll(int position, Sequence extends E> elements);
ImmutableArray drop(int n);
@Override
default ImmutableArray map(Function1 super E, ? extends R> mapper) {
return ImmutableArray.from(stream().map(mapper::apply));
}
@Override
default ImmutableArray flatMap(Function1 super E, ? extends Kind, ? extends R>> mapper) {
return ImmutableArray.from(stream().flatMap(mapper.andThen(SequenceOf::toSequence).andThen(Sequence::stream)::apply));
}
@Override
default ImmutableArray filter(Matcher1 super E> matcher) {
return ImmutableArray.from(stream().filter(matcher::match));
}
@Override
default ImmutableArray filterNot(Matcher1 super E> matcher) {
return filter(matcher.negate());
}
static ImmutableArray from(Iterable extends T> iterable) {
return from(Sequence.asStream(iterable.iterator()));
}
static ImmutableArray from(Stream extends T> stream) {
ArrayList collect = stream.collect(Collectors.toCollection(ArrayList::new));
return new PImmutableArray<>(collect);
}
@SafeVarargs
static ImmutableArray of(T... elements) {
return from(Arrays.stream(elements));
}
@SuppressWarnings("unchecked")
static ImmutableArray empty() {
return (ImmutableArray) PImmutableArray.EMPTY;
}
static Collector> toImmutableArray() {
return collectingAndThen(Collectors.toCollection(ArrayList::new), PImmutableArray::new);
}
final class PImmutableArray implements ImmutableArray, Serializable {
private static final ImmutableArray> EMPTY = new PImmutableArray<>(TreePVector.empty());
private static final Equal> EQUAL = Equal.>of().comparing(a -> a.backend);
@Serial
private static final long serialVersionUID = -6967820945086954257L;
private final PVector backend;
private PImmutableArray(Collection collection) {
this(TreePVector.from(collection));
}
private PImmutableArray(PVector backend) {
this.backend = checkNonNull(backend);
}
@Override
public int size() {
return backend.size();
}
@Override
public boolean contains(Object element) {
return backend.contains(element);
}
@Override
public Iterator iterator() {
return backend.iterator();
}
@Override
public List toList() {
return new ArrayList<>(backend);
}
@Override
public ImmutableArray append(E element) {
return new PImmutableArray<>(backend.plus(element));
}
@Override
public ImmutableArray remove(E element) {
return new PImmutableArray<>(backend.minus(element));
}
@Override
public ImmutableArray appendAll(Sequence extends E> other) {
return new PImmutableArray<>(backend.plusAll(other.toCollection()));
}
@Override
public ImmutableArray removeAll(Sequence extends E> other) {
return new PImmutableArray<>(backend.minusAll(other.toCollection()));
}
@Override
public ImmutableArray drop(int n) {
if (n >= backend.size()) {
return empty();
}
return new PImmutableArray<>(backend.subList(n, backend.size()));
}
@Override
public ImmutableArray reverse() {
return new PImmutableArray<>(backend.reversed());
}
@Override
public ImmutableArray sort(Comparator super E> comparator) {
var copy = new ArrayList<>(backend);
copy.sort(comparator);
return new PImmutableArray<>(copy);
}
@Override
public E get(int position) {
return backend.get(position);
}
@Override
public ImmutableArray remove(int position) {
return new PImmutableArray<>(backend.minus(position));
}
@Override
public ImmutableArray replace(int position, E element) {
return new PImmutableArray<>(backend.with(position, element));
}
@Override
public ImmutableArray insert(int position, E element) {
return new PImmutableArray<>(backend.plus(position, element));
}
@Override
public ImmutableArray insertAll(int position, Sequence extends E> elements) {
return new PImmutableArray<>(backend.plusAll(position, elements.toCollection()));
}
@Override
public int hashCode() {
return Objects.hash(backend);
}
@Override
public boolean equals(Object obj) {
return EQUAL.applyTo(this, obj);
}
@Override
public String toString() {
return "ImmutableArray(" + backend + ")";
}
@Serial
private Object readResolve() {
if (backend.isEmpty()) {
return EMPTY;
}
return this;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy