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

org.jsimpledb.util.ConvertedNavigableSet Maven / Gradle / Ivy

There is a newer version: 3.6.1
Show newest version

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

package org.jsimpledb.util;

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

import java.util.Comparator;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.NoSuchElementException;

/**
 * Provides a transformed view of a wrapped {@link NavigableSet} using a strictly invertable {@link Converter}.
 *
 * @param  element type of this set
 * @param  element type of the wrapped set
 */
public class ConvertedNavigableSet extends AbstractNavigableSet {

    private final NavigableSet set;
    private final Converter converter;

    /**
     * Constructor.
     *
     * @param set wrapped set
     * @param converter element converter
     * @throws IllegalArgumentException if either parameter is null
     */
    public ConvertedNavigableSet(NavigableSet set, Converter converter) {
        this(set, converter, new Bounds());
    }

    /**
     * Internal constructor.
     *
     * @param set wrapped set
     * @param converter element converter
     * @throws IllegalArgumentException if any parameter is null
     */
    ConvertedNavigableSet(NavigableSet set, Converter converter, Bounds bounds) {
        super(bounds);
        Preconditions.checkArgument(set != null, "null set");
        Preconditions.checkArgument(converter != null, "null converter");
        this.set = set;
        this.converter = converter;
    }

    public Converter getConverter() {
        return this.converter;
    }

    @Override
    public Comparator comparator() {
        return new ConvertedComparator(this.set.comparator(), this.converter);
    }

    @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.set.contains(wobj);
    }

    @Override
    public Iterator iterator() {
        return Iterators.transform(this.set.iterator(), this.converter.reverse());
    }

    @Override
    public boolean add(E obj) {
        return this.set.add(obj != null ? this.converter.convert(obj) : null);
    }

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

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

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

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

    @Override
    protected E searchBelow(E elem, boolean inclusive) {
        try {
            return super.searchBelow(elem, inclusive);
        } catch (IllegalArgumentException e) {                      // handle case where elem is out of bounds
            final E last;
            try {
                last = this.last();
            } catch (NoSuchElementException e2) {
                return null;
            }
            return this.getComparator(false).compare(elem, last) > 0 ? last : null;
        }
    }

    @Override
    protected E searchAbove(E elem, boolean inclusive) {
        try {
            return super.searchAbove(elem, inclusive);
        } catch (IllegalArgumentException e) {                      // handle case where elem is out of bounds
            final E first;
            try {
                first = this.first();
            } catch (NoSuchElementException e2) {
                return null;
            }
            return this.getComparator(false).compare(elem, first) < 0 ? first : null;
        }
    }

    @Override
    protected NavigableSet createSubSet(boolean reverse, Bounds newBounds) {
        final E lower = newBounds.getLowerBound();
        final E upper = newBounds.getUpperBound();
        final W wlower = newBounds.getLowerBoundType() != BoundType.NONE && lower != null ? this.converter.convert(lower) : null;
        final W wupper = newBounds.getUpperBoundType() != BoundType.NONE && upper != null ? this.converter.convert(upper) : null;
        NavigableSet subSet = reverse ? this.set.descendingSet() : this.set;
        if (newBounds.getLowerBoundType() != BoundType.NONE && newBounds.getUpperBoundType() != BoundType.NONE) {
            subSet = subSet.subSet(
              wlower, newBounds.getLowerBoundType().isInclusive(),
              wupper, newBounds.getUpperBoundType().isInclusive());
        } else if (newBounds.getLowerBoundType() != BoundType.NONE)
            subSet = subSet.tailSet(wlower, newBounds.getLowerBoundType().isInclusive());
        else if (newBounds.getUpperBoundType() != BoundType.NONE)
            subSet = subSet.headSet(wupper, newBounds.getUpperBoundType().isInclusive());
        return new ConvertedNavigableSet(subSet, this.converter, newBounds);
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy