
com.github.tonivade.purefun.data.ImmutableTree 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 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;
import com.github.tonivade.purefun.type.Option;
import com.github.tonivade.purefun.type.Try;
import java.io.Serial;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.Objects;
import java.util.SequencedSet;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.pcollections.PSortedSet;
import org.pcollections.TreePSet;
/**
* Similar to a TreeSet
* @param the type of elements in this tree
*/
public interface ImmutableTree extends Sequence {
Comparator comparator();
NavigableSet toNavigableSet();
default SequencedSet toSequencedSet() {
return toNavigableSet();
}
default SortedSet toSortedSet() {
return toNavigableSet();
}
@Override
ImmutableTree append(E element);
@Override
ImmutableTree remove(E element);
@Override
ImmutableTree appendAll(Sequence extends E> other);
@Override
ImmutableTree removeAll(Sequence extends E> other);
@Override
ImmutableTree reverse();
Option head();
Option tail();
ImmutableTree headTree(E value);
ImmutableTree tailTree(E value);
Option higher(E value);
Option lower(E value);
Option ceiling(E value);
Option floor(E value);
@Override
default ImmutableTree map(Function1 super E, ? extends R> mapper) {
return ImmutableTree.from(naturalOrder(), stream().map(mapper::apply));
}
default ImmutableTree map(Comparator super R> comparator, Function1 super E, ? extends R> mapper) {
return ImmutableTree.from(comparator, stream().map(mapper::apply));
}
@Override
default ImmutableTree flatMap(Function1 super E, ? extends Kind, ? extends R>> mapper) {
return ImmutableTree.from(naturalOrder(), stream().flatMap(mapper.andThen(SequenceOf::toSequence).andThen(Sequence::stream)::apply));
}
default ImmutableTree flatMap(Comparator super R> comparator, Function1 super E, ? extends Kind, ? extends R>> mapper) {
return ImmutableTree.from(comparator, stream().flatMap(mapper.andThen(SequenceOf::toSequence).andThen(Sequence::stream)::apply));
}
@Override
default ImmutableTree filter(Matcher1 super E> matcher) {
return ImmutableTree.from(comparator(), stream().filter(matcher::match));
}
@Override
default ImmutableTree filterNot(Matcher1 super E> matcher) {
return filter(matcher.negate());
}
static ImmutableTree from(Iterable extends T> iterable) {
return from(naturalOrder(), Sequence.asStream(iterable.iterator()));
}
static ImmutableTree from(Comparator super T> comparator, Iterable extends T> iterable) {
return from(comparator, Sequence.asStream(iterable.iterator()));
}
static ImmutableTree from(Stream extends T> stream) {
return new PImmutableTree<>(naturalOrder(), stream.collect(Collectors.toCollection(TreeSet::new)));
}
static ImmutableTree from(Comparator super T> comparator, Stream extends T> stream) {
return new PImmutableTree<>(comparator, stream.collect(Collectors.toCollection(TreeSet::new)));
}
@SafeVarargs
static > ImmutableTree of(T... elements) {
return new PImmutableTree<>(naturalOrder(), Arrays.asList(elements));
}
@SuppressWarnings("unchecked")
static ImmutableTree empty() {
return (ImmutableTree) PImmutableTree.EMPTY;
}
static Collector> toImmutableTree() {
return collectingAndThen(Collectors.toCollection(TreeSet::new), PImmutableTree::new);
}
@SuppressWarnings("unchecked")
private static Comparator naturalOrder() {
return (Comparator) Comparator.naturalOrder();
}
final class PImmutableTree implements ImmutableTree, Serializable {
@Serial
private static final long serialVersionUID = 3964148260438348347L;
private static final ImmutableTree> EMPTY = new PImmutableTree<>(TreePSet.empty(naturalOrder()));
private static final Equal> EQUAL =
Equal.>of().comparing(a -> a.backend);
private final PSortedSet backend;
private PImmutableTree(Comparator super E> comparator, Collection extends E> backend) {
this(TreePSet.from(comparator, backend));
}
private PImmutableTree(SortedSet backend) {
this(TreePSet.fromSortedSet(backend));
}
private PImmutableTree(PSortedSet backend) {
this.backend = checkNonNull(backend);
}
@SuppressWarnings("unchecked")
@Override
public Comparator comparator() {
return (Comparator) backend.comparator();
}
@Override
public int size() {
return backend.size();
}
@Override
public boolean contains(Object element) {
return backend.contains(element);
}
@Override
public ImmutableTree reverse() {
return new PImmutableTree<>(backend.descendingSet());
}
@Override
public ImmutableTree append(E element) {
return new PImmutableTree<>(backend.plus(element));
}
@Override
public ImmutableTree remove(E element) {
return new PImmutableTree<>(backend.minus(element));
}
@Override
public ImmutableTree appendAll(Sequence extends E> other) {
return new PImmutableTree<>(backend.plusAll(other.toCollection()));
}
@Override
public ImmutableTree removeAll(Sequence extends E> other) {
return new PImmutableTree<>(backend.minusAll(other.toCollection()));
}
@Override
public Option head() {
return Try.of(backend::first).toOption();
}
@Override
public Option tail() {
return Try.of(backend::last).toOption();
}
@Override
public ImmutableTree headTree(E toElement) {
return new PImmutableTree<>(backend.headSet(toElement, false));
}
@Override
public ImmutableTree tailTree(E fromElement) {
return new PImmutableTree<>(backend.tailSet(fromElement, false));
}
@Override
public Option higher(E value) {
return Option.of(() -> backend.higher(value));
}
@Override
public Option lower(E value) {
return Option.of(() -> backend.lower(value));
}
@Override
public Option ceiling(E value) {
return Option.of(() -> backend.ceiling(value));
}
@Override
public Option floor(E value) {
return Option.of(() -> backend.floor(value));
}
@Override
public Iterator iterator() {
return backend.iterator();
}
@Override
public NavigableSet toNavigableSet() {
return new TreeSet<>(backend);
}
@Override
public int hashCode() {
return Objects.hash(backend);
}
@Override
public boolean equals(Object obj) {
return EQUAL.applyTo(this, obj);
}
@Override
public String toString() {
return "ImmutableTree(" + backend + ")";
}
@Serial
private Object readResolve() {
if (backend.isEmpty()) {
return EMPTY;
}
return this;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy