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

net.sf.saxon.z.IntArraySet Maven / Gradle / Ivy

There is a newer version: 10.5
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2013 Saxonica Limited.
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package net.sf.saxon.z;


import net.sf.saxon.tree.util.FastStringBuffer;

import java.io.Serializable;
import java.util.Arrays;

/**
 * Set of int values. This class is modelled on the java.net.Set interface, but it does
 * not implement this interface, because the set members are int's rather than Objects.
 * 

* This implementation of a set of integers is optimized to use very little storage * and to provide fast comparison of two sets. The equals() method determines whether * two sets contain the same integers. *

* This implementation is not efficient at adding new integers to the set. It creates a new * array each time you do that. *

* Not thread safe. * * @author Michael Kay */ public class IntArraySet extends AbstractIntSet implements Serializable, IntSet { public static final int[] EMPTY_INT_ARRAY = new int[0]; /** * The array of integers, which will always be sorted */ private int[] contents; /** * Hashcode, evaluated lazily */ private int hashCode = -1; /** * Create an empty set */ public IntArraySet() { contents = EMPTY_INT_ARRAY; } /** * Create a set containing integers from the specified IntHashSet * @param input the set to be copied */ public IntArraySet(IntHashSet input) { // exploits the fact that getValues() constructs a new array contents = input.getValues(); //System.err.println("new IntArraySet(" + contents.length + ")"); Arrays.sort(contents); } /** * Create one IntArraySet as a copy of another * @param input the set to be copied */ public IntArraySet(IntArraySet input) { contents = new int[input.contents.length]; System.arraycopy(input.contents, 0, contents, 0, contents.length); } public IntSet copy() { IntArraySet i2 = new IntArraySet(); i2.contents = new int[contents.length]; System.arraycopy(contents, 0, i2.contents, 0, contents.length); //i2.contents = Arrays.copyOf(contents, contents.length); return i2; } public IntSet mutableCopy() { return copy(); } public void clear() { contents = EMPTY_INT_ARRAY; hashCode = -1; } public int size() { return contents.length; } public boolean isEmpty() { return contents.length == 0; } /** * Get the set of integer values as an array * @return a sorted array of integers */ public int[] getValues() { return contents; } public boolean contains(int value) { return Arrays.binarySearch(contents, value) >= 0; } public boolean remove(int value) { hashCode = -1; int pos = Arrays.binarySearch(contents, value); if (pos < 0) { return false; } int[] newArray = new int[contents.length - 1]; if (pos > 0) { // copy the items before the one that's being removed System.arraycopy(contents, 0, newArray, 0, pos); } if (pos < newArray.length) { // copy the items after the one that's being removed System.arraycopy(contents, pos+1, newArray, pos, contents.length - pos); } contents = newArray; return true; } /** * Add an integer to the set * @param value the integer to be added * @return true if the integer was added, false if it was already present */ public boolean add(int value) { hashCode = -1; if (contents.length == 0) { contents = new int[] {value}; return true; } int pos = Arrays.binarySearch(contents, value); if (pos >= 0) { return false; // value was already present } pos = -pos - 1; // new insertion point int[] newArray = new int[contents.length + 1]; if (pos > 0) { // copy the items before the insertion point System.arraycopy(contents, 0, newArray, 0, pos); } newArray[pos] = value; if (pos < contents.length) { // copy the items after the insertion point System.arraycopy(contents, pos, newArray, pos+1, newArray.length - pos); } contents = newArray; return true; } /** * Get the first value in the set. * @return the first value in the set, in sorted order * @throws ArrayIndexOutOfBoundsException if the set is empty */ public int getFirst() { return contents[0]; } /** * Get an iterator over the values * @return an iterator over the values, which will be delivered in sorted order */ public IntIterator iterator() { return new IntArraySetIterator(); } /** * Form a new set that is the union of this set with another set. * @param other the other set * @return the union of the two sets */ public IntSet union(IntSet other) { // Look for special cases: one set empty, or both sets equal if (size() == 0) { return other.copy(); } else if (other.isEmpty()) { return copy(); } else if (other == IntUniversalSet.getInstance()) { return other; } else if (other instanceof IntComplementSet) { return other.union(this); } if (equals(other)) { return copy(); } if (other instanceof IntArraySet) { // Form the union by a merge of the two sorted arrays int[] merged = new int[size() + other.size()]; int[] a = contents; int[] b = ((IntArraySet)other).contents; int m = a.length, n = b.length; int o=0, i=0, j=0; while (true) { if (a[i] < b[j]) { merged[o++] = a[i++]; } else if (b[j] < a[i]) { merged[o++] = b[j++]; } else { merged[o++] = a[i++]; j++; } if (i == m) { System.arraycopy(b, j, merged, o, n-j); o += (n-j); return make(merged, o); } else if (j == n) { System.arraycopy(a, i, merged, o, m-i); o += (m-i); return make(merged, o); } } } else { return super.union(other); } } /** * Factory method to construct a set from an array of integers * @param in the array of integers, which must be in ascending order * @param size the number of elements in the array that are significant * @return the constructed set */ public static IntArraySet make(int[] in, int size) { int[] out; if (in.length == size) { out = in; } else { out = new int[size]; System.arraycopy(in, 0, out, 0, size); } return new IntArraySet(out); } private IntArraySet(int[] content) { contents = content; } public String toString() { FastStringBuffer sb = new FastStringBuffer(contents.length*4); for (int i=0; i





© 2015 - 2024 Weber Informatics LLC | Privacy Policy