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

squidpony.squidmath.RegionMap Maven / Gradle / Ivy

Go to download

SquidLib platform-independent logic and utility code. Please refer to https://github.com/SquidPony/SquidLib .

There is a newer version: 3.0.6
Show newest version
package squidpony.squidmath;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

/**
 * A small extension of OrderedMap that specifically handles {@code short[]} regions as produced by {@link CoordPacker}.
 * The methods {@link #allAt(int, int)}, {@link #containsRegion(short[])}, and {@link #regionsContaining(int, int)} are
 * added here, and the minor extra work needed to handle array keys in OrderedMap is taken care of automatically.
 * {@link #toString()} also produces nicer output by default for this usage, with the keys printed in a usable way.
 * Created by Tommy Ettinger on 11/24/2016.
 */
public class RegionMap extends OrderedMap implements Serializable {
    private static final long serialVersionUID = 2L;

    public RegionMap(final int expected, final float f) {
        super(expected, f, CrossHash.shortHasher);
        CoordPacker.init();
    }

    /**
     * Creates a new RegionMap with 0.75f as load factor.
     *
     * @param expected the expected number of elements in the RegionMap.
     */
    public RegionMap(final int expected) {
        this(expected, DEFAULT_LOAD_FACTOR);
    }

    /**
     * Creates a new RegionMap with initial expected 16 entries and 0.75f as load factor.
     */
    public RegionMap() {
        this(DEFAULT_INITIAL_SIZE, DEFAULT_LOAD_FACTOR);
    }

    /**
     * Creates a new RegionMap copying a given one.
     *
     * @param m a {@link Map} to be copied into the new RegionMap.
     * @param f the load factor.
     */
    public RegionMap(final Map m, final float f) {
        this(m.size(), f);
        putAll(m);
    }

    /**
     * Creates a new RegionMap with 0.75f as load factor copying a given one.
     *
     * @param m a {@link Map} to be copied into the new RegionMap.
     */
    public RegionMap(final Map m) {
        this(m, DEFAULT_LOAD_FACTOR);
    }

    /**
     * Creates a new RegionMap using the elements of two parallel arrays.
     *
     * @param keyArray   the array of keys of the new RegionMap.
     * @param valueArray the array of corresponding values in the new RegionMap.
     * @param f          the load factor.
     * @throws IllegalArgumentException if k and v have different lengths.
     */
    public RegionMap(final short[][] keyArray, final V[] valueArray, final float f) {
        this(keyArray.length, f);
        if (keyArray.length != valueArray.length)
            throw new IllegalArgumentException("The key array and the value array have different lengths (" + keyArray.length + " and " + valueArray.length + ")");
        for (int i = 0; i < keyArray.length; i++)
            put(keyArray[i], valueArray[i]);
    }

    /**
     * Creates a new RegionMap using the elements of two parallel arrays.
     *
     * @param keyColl   the collection of keys of the new RegionMap.
     * @param valueColl the collection of corresponding values in the new RegionMap.
     * @param f         the load factor.
     * @throws IllegalArgumentException if k and v have different lengths.
     */
    public RegionMap(final Collection keyColl, final Collection valueColl, final float f) {
        this(keyColl.size(), f);
        if (keyColl.size() != valueColl.size())
            throw new IllegalArgumentException("The key array and the value array have different lengths (" + keyColl.size() + " and " + valueColl.size() + ")");
        Iterator ki = keyColl.iterator();
        Iterator vi = valueColl.iterator();
        while (ki.hasNext() && vi.hasNext()) {
            put(ki.next(), vi.next());
        }
    }

    /**
     * Creates a new RegionMap with 0.75f as load factor using the elements of two parallel arrays.
     *
     * @param keyArray   the array of keys of the new RegionMap.
     * @param valueArray the array of corresponding values in the new RegionMap.
     * @throws IllegalArgumentException if k and v have different lengths.
     */
    public RegionMap(final short[][] keyArray, final V[] valueArray) {
        this(keyArray, valueArray, DEFAULT_LOAD_FACTOR);
    }

    /**
     * Gets a List of all values associated with regions containing a given x,y point.
     *
     * @param x the x coordinate of the point in question
     * @param y the y coordinate of the point in question
     * @return an ArrayList of all V values corresponding to regions containing the given x,y point.
     */
    public ArrayList allAt(int x, int y) {
        ArrayList found = new ArrayList<>(size);
        OrderedSet regions = CoordPacker.findManyPacked(x, y, keySet());
        int count = regions.size;
        for (int i = 0; i < count; i++) {
            found.add(get(regions.getAt(i)));
        }
        return found;
    }

    /**
     * Checks if a region, stored as packed data (possibly from CoordPacker or this class) overlaps with regions stored
     * in this object as keys. Returns true if there is any overlap, false otherwise
     *
     * @param region the packed region to check for overlap with regions this stores values for
     * @return true if the region overlaps at all, false otherwise
     */
    public boolean containsRegion(short[] region) {
        return CoordPacker.regionsContain(region, keySet());
    }

    /**
     * Gets a List of all regions containing a given x,y point.
     *
     * @param x the x coordinate of the point in question
     * @param y the y coordinate of the point in question
     * @return an ArrayList of all regions in this data structure containing the given x,y point.
     */
    public OrderedSet regionsContaining(int x, int y) {
        return CoordPacker.findManyPacked(x, y, keySet());
    }

    public String toString(String separator) {
        return toString(separator, false);
    }

    @Override
    public String toString() {
        return toString(", ", true);
    }

    private String toString(String separator, boolean braces) {
        if (size == 0) return braces ? "{}" : "";
        StringBuilder buffer = new StringBuilder(32);
        if (braces) buffer.append('{');
        short[][] keyTable = this.key;
        V[] valueTable = this.value;
        int i = keyTable.length;
        while (i-- > 0) {
            short[] key = keyTable[i];
            if (key == null) continue;
            buffer.append("Packed Region:")
                    .append(CoordPacker.encodeASCII(key))
                    .append('=')
                    .append(valueTable[i]);
            break;
        }
        while (i-- > 0) {
            short[] key = keyTable[i];
            if (key == null) continue;
            buffer.append(separator)
                    .append("Packed Region:")
                    .append(CoordPacker.encodeASCII(key))
                    .append('=')
                    .append(valueTable[i]);
        }
        if (braces) buffer.append('}');
        return buffer.toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy