All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.tonivade.purefun.data.ImmutableArray Maven / Gradle / Ivy

/*
 * Copyright (c) 2018-2020, Antonio Gabriel Muñoz Conejo 
 * Distributed under the terms of the MIT License
 */
package com.github.tonivade.purefun.data;

import static java.util.Collections.emptyList;
import static java.util.Collections.unmodifiableList;
import static java.util.stream.Collectors.collectingAndThen;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
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 com.github.tonivade.purefun.Equal;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Matcher1;

public interface ImmutableArray extends Sequence {

  List toList();

  @Override
  ImmutableArray append(E element);
  @Override
  ImmutableArray remove(E element);
  @Override
  ImmutableArray appendAll(Sequence other);
  @Override
  ImmutableArray removeAll(Sequence other);

  @Override
  ImmutableArray reverse();
  ImmutableArray sort(Comparator 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 elements);

  default ImmutableArray drop(int n) {
    return ImmutableArray.from(stream().skip(n));
  }

  @Override
  default  ImmutableArray map(Function1 mapper) {
    return ImmutableArray.from(stream().map(mapper::apply));
  }

  @Override
  default  ImmutableArray flatMap(Function1> mapper) {
    return ImmutableArray.from(stream().flatMap(mapper.andThen(Sequence::stream)::apply));
  }

  @Override
  default ImmutableArray filter(Matcher1 matcher) {
    return ImmutableArray.from(stream().filter(matcher::match));
  }

  @Override
  default ImmutableArray filterNot(Matcher1 matcher) {
    return filter(matcher.negate());
  }

  static  ImmutableArray from(Iterable iterable) {
    return from(Sequence.asStream(iterable.iterator()));
  }

  static  ImmutableArray from(Stream stream) {
    return new JavaBasedImmutableArray<>(stream.collect(Collectors.toList()));
  }

  @SafeVarargs
  static  ImmutableArray of(T... elements) {
    return new JavaBasedImmutableArray<>(Arrays.asList(elements));
  }

  static  ImmutableArray empty() {
    return new JavaBasedImmutableArray<>(emptyList());
  }

  static  Collector> toImmutableArray() {
    return collectingAndThen(Collectors.toList(), JavaBasedImmutableArray::new);
  }

  final class JavaBasedImmutableArray implements ImmutableArray, Serializable {

    private static final long serialVersionUID = 5728385935547829871L;

    private static final Equal> EQUAL = 
        Equal.>of().comparing(a -> a.backend);

    private final List backend;

    private JavaBasedImmutableArray(List backend) {
      this.backend = unmodifiableList(backend);
    }

    @Override
    public int size() {
      return backend.size();
    }

    @Override
    public boolean contains(E element) {
      return backend.contains(element);
    }

    @Override
    public ImmutableArray reverse() {
      List list = toList();
      Collections.reverse(list);
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public ImmutableArray sort(Comparator comparator) {
      List list = toList();
      Collections.sort(list, comparator);
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public Iterator iterator() {
      return backend.iterator();
    }

    @Override
    public ImmutableArray append(E element) {
      List list = toList();
      list.add(element);
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public ImmutableArray remove(E element) {
      List list = toList();
      list.remove(element);
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public ImmutableArray appendAll(Sequence other) {
      List list = toList();
      list.addAll(new SequenceCollection<>(other));
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public ImmutableArray removeAll(Sequence other) {
      List list = toList();
      list.removeAll(new SequenceCollection<>(other));
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public E get(int position) {
      return backend.get(position);
    }

    @Override
    public ImmutableArray replace(int position, E element) {
      List list = toList();
      list.set(position, element);
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public ImmutableArray remove(int position) {
      List list = toList();
      list.remove(position);
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public ImmutableArray insert(int position, E element) {
      List list = toList();
      list.add(position, element);
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public ImmutableArray insertAll(int position, Sequence elements) {
      List list = toList();
      list.addAll(position, new SequenceCollection<>(elements));
      return new JavaBasedImmutableArray<>(list);
    }

    @Override
    public List toList() {
      return new ArrayList<>(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 "ImmutableArray(" + backend + ")";
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy