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

nl.vpro.util.TransformingList Maven / Gradle / Ivy

There is a newer version: 5.3.1
Show newest version
package nl.vpro.util;

import java.util.*;
import java.util.function.Function;

/**
 * @author Michiel Meeuwissen
 * @since 4.3
 */
public class TransformingList extends AbstractList implements TransformingCollection, List> {

    private final List wrapped;
    private final List> transformed;
    private final Function transformer;
    private final Function producer;

    public TransformingList(List wrapped, Function transformer, Function producer) {
        this.wrapped = wrapped;
        this.transformed = new ArrayList<>(Collections.nCopies(wrapped.size(), null));
        this.transformer = transformer;
        this.producer = producer;
    }


    @Override
    public T get(int index) {
        return transform(index, wrapped.get(index));
    }

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

    @Override
    public boolean remove(Object o) {
        return TransformingCollection.super.remove(o);
    }

    @Override
    public T set(int i, T toSet) {
        S newObject = wrapped.set(i, produce(toSet));
        return transform(i, newObject);
    }

    @Override
    public void add(int i, T toAdd) {
        transformed.add(i, null);
        wrapped.add(i, produce(toAdd));
    }

    @Override
    public T remove(int i) {
        S removed = wrapped.remove(i);
        transformed.remove(i);
        return transform(removed);
    }

    @Override
    public T transform(S entry) {
        return transformer.apply(entry);
    }

    @Override
    public T transform(int i, S entry) {
        Optional trans = transformed.get(i);
        if (trans == null) {
            trans = Optional.ofNullable(transformer.apply(entry));
            transformed.set(i, trans);
        }
        return trans.orElse(null);
    }

    @Override
    public S produce(T entry) {
        return producer.apply(entry);

    }

    @Override
    public List newWrap() {
        return new ArrayList<>();

    }

    @Override
    public List newFiltered() {
        return new ArrayList<>();

    }

    @Override
    public List unwrap() {
        return wrapped;
    }

}