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

io.permazen.util.ConvertedList Maven / Gradle / Ivy

There is a newer version: 5.1.0
Show newest version

/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package io.permazen.util;

import com.google.common.base.Converter;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterators;

import java.util.AbstractList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Provides a transformed view of a wrapped {@link List} using a strictly invertable {@link Converter}.
 *
 * @param  element type of this list
 * @param  element type of the wrapped list
 */
public class ConvertedList extends AbstractList {

    private final List list;
    private final Converter converter;

    /**
     * Constructor.
     *
     * @param list wrapped list
     * @param converter element converter
     * @throws IllegalArgumentException if either parameter is null
     */
    public ConvertedList(List list, Converter converter) {
        Preconditions.checkArgument(list != null, "null list");
        Preconditions.checkArgument(converter != null, "null converter");
        this.list = list;
        this.converter = converter;
    }

    /**
     * Get the wrapped {@link List}.
     *
     * @return the wrapped {@link List}.
     */
    public List getWrappedList() {
        return this.list;
    }

    /**
     * Get the {@link Converter} associated with this instance.
     *
     * @return associated {@link Converter}
     */
    public Converter getConverter() {
        return this.converter;
    }

    @Override
    public E get(int index) {
        final W value = this.list.get(index);
        return value != null ? this.converter.reverse().convert(value) : null;
    }

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

    @Override
    public boolean isEmpty() {
        return this.list.isEmpty();
    }

    @Override
    public E set(int index, E elem) {
        final W welem = elem != null ? this.converter.convert(elem) : null;
        final W prev = this.list.set(index, welem);
        return prev != null ? this.converter.reverse().convert(prev) : null;
    }

    @Override
    public void add(int index, E elem) {
        final W welem = elem != null ? this.converter.convert(elem) : null;
        this.list.add(index, welem);
    }

    @Override
    public boolean addAll(int index, Collection elems) {
        return this.list.addAll(index, elems.stream()
          .map(elem -> elem != null ? this.converter.convert(elem) : null)
          .collect(Collectors.toList()));
    }

    @Override
    @SuppressWarnings("unchecked")
    public boolean contains(Object obj) {
        W wobj = null;
        if (obj != null) {
            try {
                wobj = this.converter.convert((E)obj);
            } catch (ClassCastException e) {
                return false;
            }
        }
        return this.list.contains(wobj);
    }

    @Override
    @SuppressWarnings("unchecked")
    public int indexOf(Object obj) {
        W wobj = null;
        if (obj != null) {
            try {
                wobj = this.converter.convert((E)obj);
            } catch (ClassCastException e) {
                return -1;
            }
        }
        return this.list.indexOf(wobj);
    }

    @Override
    @SuppressWarnings("unchecked")
    public int lastIndexOf(Object obj) {
        W wobj = null;
        if (obj != null) {
            try {
                wobj = this.converter.convert((E)obj);
            } catch (ClassCastException e) {
                return -1;
            }
        }
        return this.list.lastIndexOf(wobj);
    }

    @Override
    public void clear() {
        this.list.clear();
    }

    @Override
    public E remove(int index) {
        final W welem = this.list.remove(index);
        return welem != null ? this.converter.reverse().convert(welem) : null;
    }

    @Override
    public CloseableIterator iterator() {
        final Iterator wrappedIterator = this.list.iterator();
        final Iterator convertedIterator = Iterators.transform(wrappedIterator, this.converter.reverse());
        return wrappedIterator instanceof CloseableIterator ?
          CloseableIterator.wrap(convertedIterator, (CloseableIterator)wrappedIterator) :
          CloseableIterator.wrap(convertedIterator);
    }

    @Override
    public Spliterator spliterator() {
        return new ConvertedSpliterator(this.list.spliterator(), this.converter.reverse());
    }

    @Override
    public Stream stream() {
        return this.list.stream().map(this.converter.reverse()::convert);
    }

    @Override
    public List subList(int min, int max) {
        return new ConvertedList<>(this.list.subList(min, max), this.converter);
    }

    @Override
    protected void removeRange(int min, int max) {
        this.list.subList(min, max).clear();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy